x/tools/go/ssa: Accept struct conversions that ignore tags

This is now allowed in go1.8.

Fixes golang/go#19646.

Change-Id: Iece4fd2a881144bdbe841e0a26ba4348d6b8828e
Reviewed-on: https://go-review.googlesource.com/38452
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Spencer Nelson 2017-03-22 14:59:57 -04:00 committed by Alan Donovan
parent bc6db94186
commit 2a5864fcfb
6 changed files with 53 additions and 2 deletions

View File

@ -147,7 +147,7 @@ func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value {
// //
func isValuePreserving(ut_src, ut_dst types.Type) bool { func isValuePreserving(ut_src, ut_dst types.Type) bool {
// Identical underlying types? // Identical underlying types?
if types.Identical(ut_dst, ut_src) { if structTypesIdentical(ut_dst, ut_src) {
return true return true
} }

7
go/ssa/identical.go Normal file
View File

@ -0,0 +1,7 @@
// +build go1.8
package ssa
import "go/types"
var structTypesIdentical = types.IdenticalIgnoreTags

7
go/ssa/identical_17.go Normal file
View File

@ -0,0 +1,7 @@
// +build !go1.8
package ssa
import "go/types"
var structTypesIdentical = types.Identical

9
go/ssa/identical_test.go Normal file
View File

@ -0,0 +1,9 @@
//+build go1.8
package ssa_test
import "testing"
func TestValueForExprStructConv(t *testing.T) {
testValueForExpr(t, "testdata/structconv.go")
}

View File

@ -194,12 +194,16 @@ func checkVarValue(t *testing.T, prog *ssa.Program, pkg *ssa.Package, ref []ast.
// Ensure that, in debug mode, we can determine the ssa.Value // Ensure that, in debug mode, we can determine the ssa.Value
// corresponding to every ast.Expr. // corresponding to every ast.Expr.
func TestValueForExpr(t *testing.T) { func TestValueForExpr(t *testing.T) {
testValueForExpr(t, "testdata/valueforexpr.go")
}
func testValueForExpr(t *testing.T, testfile string) {
if runtime.GOOS == "android" { if runtime.GOOS == "android" {
t.Skipf("no testdata dir on %s", runtime.GOOS) t.Skipf("no testdata dir on %s", runtime.GOOS)
} }
conf := loader.Config{ParserMode: parser.ParseComments} conf := loader.Config{ParserMode: parser.ParseComments}
f, err := conf.ParseFile("testdata/valueforexpr.go", nil) f, err := conf.ParseFile(testfile, nil)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return

24
go/ssa/testdata/structconv.go vendored Normal file
View File

@ -0,0 +1,24 @@
//+build ignore
// This file is the input to TestValueForExprStructConv in identical_test.go,
// which uses the same framework as TestValueForExpr does in source_test.go.
//
// In Go 1.8, struct conversions are permitted even when the struct types have
// different tags. This wasn't permitted in earlier versions of Go, so this file
// exists separately from valueforexpr.go to just test this behavior in Go 1.8
// and later.
package main
type t1 struct {
x int
}
type t2 struct {
x int `tag`
}
func main() {
var tv1 t1
var tv2 t2 = /*@ChangeType*/ (t2(tv1))
_ = tv2
}