summaryrefslogtreecommitdiff
path: root/libgo/go/reflect
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-02-05 14:33:27 -0800
committerIan Lance Taylor <iant@golang.org>2020-02-15 09:14:10 -0800
commit0b3c2eed35d608d6541ecf004a9576b4eae0b4ef (patch)
treec92c05d53eb054d8085d069800f4e9b586fef5a3 /libgo/go/reflect
parent17edb3310d8ce9d5f6c9e53f6c1f7d611c2a5a41 (diff)
downloadgcc-0b3c2eed35d608d6541ecf004a9576b4eae0b4ef.tar.gz
libgo: update to Go1.14rc1 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/218017
Diffstat (limited to 'libgo/go/reflect')
-rw-r--r--libgo/go/reflect/all_test.go21
-rw-r--r--libgo/go/reflect/type.go18
2 files changed, 36 insertions, 3 deletions
diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go
index c9ed0a9e52d..33d02aea849 100644
--- a/libgo/go/reflect/all_test.go
+++ b/libgo/go/reflect/all_test.go
@@ -4864,6 +4864,9 @@ func TestStructOfExportRules(t *testing.T) {
if exported != test.exported {
t.Errorf("test-%d: got exported=%v want exported=%v", i, exported, test.exported)
}
+ if field.PkgPath != test.field.PkgPath {
+ t.Errorf("test-%d: got PkgPath=%q want pkgPath=%q", i, field.PkgPath, test.field.PkgPath)
+ }
})
}
}
@@ -5327,6 +5330,24 @@ func TestStructOfTooManyFields(t *testing.T) {
}
}
+func TestStructOfDifferentPkgPath(t *testing.T) {
+ fields := []StructField{
+ {
+ Name: "f1",
+ PkgPath: "p1",
+ Type: TypeOf(int(0)),
+ },
+ {
+ Name: "f2",
+ PkgPath: "p2",
+ Type: TypeOf(int(0)),
+ },
+ }
+ shouldPanic(func() {
+ StructOf(fields)
+ })
+}
+
func TestChanOf(t *testing.T) {
// check construction and use of type not in binary
type T string
diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go
index a3506748a25..9c003a43dd9 100644
--- a/libgo/go/reflect/type.go
+++ b/libgo/go/reflect/type.go
@@ -1993,6 +1993,7 @@ func StructOf(fields []StructField) Type {
lastzero := uintptr(0)
repr = append(repr, "struct {"...)
+ pkgpath := ""
for i, field := range fields {
if field.Name == "" {
panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name")
@@ -2003,11 +2004,18 @@ func StructOf(fields []StructField) Type {
if field.Type == nil {
panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type")
}
- f := runtimeStructField(field)
+ f, fpkgpath := runtimeStructField(field)
ft := f.typ
if ft.kind&kindGCProg != 0 {
hasGCProg = true
}
+ if fpkgpath != "" {
+ if pkgpath == "" {
+ pkgpath = fpkgpath
+ } else if pkgpath != fpkgpath {
+ panic("reflect.Struct: fields with different PkgPath " + pkgpath + " and " + fpkgpath)
+ }
+ }
// Update string and hash
name := *f.name
@@ -2229,7 +2237,10 @@ func StructOf(fields []StructField) Type {
return addToCache(&typ.rtype)
}
-func runtimeStructField(field StructField) structField {
+// runtimeStructField takes a StructField value passed to StructOf and
+// returns both the corresponding internal representation, of type
+// structField, and the pkgpath value to use for this field.
+func runtimeStructField(field StructField) (structField, string) {
if field.Anonymous && field.PkgPath != "" {
panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
}
@@ -2263,13 +2274,14 @@ func runtimeStructField(field StructField) structField {
s := field.PkgPath
pkgPath = &s
}
- return structField{
+ f := structField{
name: name,
pkgPath: pkgPath,
typ: field.Type.common(),
tag: tag,
offsetEmbed: offsetEmbed,
}
+ return f, field.PkgPath
}
// typeptrdata returns the length in bytes of the prefix of t