aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--libgo/go/encoding/json/decode_test.go16
-rw-r--r--libgo/go/encoding/json/encode.go2
-rw-r--r--libgo/go/encoding/xml/marshal_test.go10
-rw-r--r--libgo/go/encoding/xml/typeinfo.go2
-rw-r--r--libgo/go/reflect/export_test.go4
-rw-r--r--libgo/go/reflect/type.go2
-rw-r--r--libgo/go/reflect/value.go29
8 files changed, 48 insertions, 19 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index b17ca93b24c..f325bb33ecb 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-10c1d6756ed1dcc814c49921c2a5e27f4677e0e6
+012ab5cb2ef1c26e8023ce90d3a2bba174da7b30
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go
index 8aa158f08cd..51b15ef997c 100644
--- a/libgo/go/encoding/json/decode_test.go
+++ b/libgo/go/encoding/json/decode_test.go
@@ -118,6 +118,7 @@ type Top struct {
Loop
Embed0p // has Point with X, Y, used
Embed0q // has Point with Z, used
+ embed // contains exported field
}
type Embed0 struct {
@@ -148,6 +149,10 @@ type Embed0q struct {
Point
}
+type embed struct {
+ Q int
+}
+
type Loop struct {
Loop1 int `json:",omitempty"`
Loop2 int `json:",omitempty"`
@@ -331,7 +336,8 @@ var unmarshalTests = []unmarshalTest{
"Loop2": 14,
"X": 15,
"Y": 16,
- "Z": 17
+ "Z": 17,
+ "Q": 18
}`,
ptr: new(Top),
out: Top{
@@ -361,6 +367,9 @@ var unmarshalTests = []unmarshalTest{
Embed0q: Embed0q{
Point: Point{Z: 17},
},
+ embed: embed{
+ Q: 18,
+ },
},
},
{
@@ -507,12 +516,15 @@ func TestMarshalEmbeds(t *testing.T) {
Embed0q: Embed0q{
Point: Point{Z: 17},
},
+ embed: embed{
+ Q: 18,
+ },
}
b, err := Marshal(top)
if err != nil {
t.Fatal(err)
}
- want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17}"
+ want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17,\"Q\":18}"
if string(b) != want {
t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want)
}
diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go
index 90782deb70b..e829a930768 100644
--- a/libgo/go/encoding/json/encode.go
+++ b/libgo/go/encoding/json/encode.go
@@ -1022,7 +1022,7 @@ func typeFields(t reflect.Type) []field {
// Scan f.typ for fields to include.
for i := 0; i < f.typ.NumField(); i++ {
sf := f.typ.Field(i)
- if sf.PkgPath != "" { // unexported
+ if sf.PkgPath != "" && !sf.Anonymous { // unexported
continue
}
tag := sf.Tag.Get("json")
diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go
index 66675d7abc4..ef6c20e949b 100644
--- a/libgo/go/encoding/xml/marshal_test.go
+++ b/libgo/go/encoding/xml/marshal_test.go
@@ -139,6 +139,7 @@ type EmbedA struct {
EmbedC
EmbedB EmbedB
FieldA string
+ embedD
}
type EmbedB struct {
@@ -153,6 +154,11 @@ type EmbedC struct {
FieldC string
}
+type embedD struct {
+ fieldD string
+ FieldE string // Promoted and visible when embedD is embedded.
+}
+
type NameCasing struct {
XMLName struct{} `xml:"casing"`
Xy string
@@ -711,6 +717,9 @@ var marshalTests = []struct {
},
},
FieldA: "A.A",
+ embedD: embedD{
+ FieldE: "A.D.E",
+ },
},
ExpectXML: `<EmbedA>` +
`<FieldB>A.C.B</FieldB>` +
@@ -724,6 +733,7 @@ var marshalTests = []struct {
`<FieldC>A.B.C.C</FieldC>` +
`</EmbedB>` +
`<FieldA>A.A</FieldA>` +
+ `<FieldE>A.D.E</FieldE>` +
`</EmbedA>`,
},
diff --git a/libgo/go/encoding/xml/typeinfo.go b/libgo/go/encoding/xml/typeinfo.go
index 22248d20a6d..6766b88f09a 100644
--- a/libgo/go/encoding/xml/typeinfo.go
+++ b/libgo/go/encoding/xml/typeinfo.go
@@ -60,7 +60,7 @@ func getTypeInfo(typ reflect.Type) (*typeInfo, error) {
n := typ.NumField()
for i := 0; i < n; i++ {
f := typ.Field(i)
- if f.PkgPath != "" || f.Tag.Get("xml") == "-" {
+ if (f.PkgPath != "" && !f.Anonymous) || f.Tag.Get("xml") == "-" {
continue // Private field
}
diff --git a/libgo/go/reflect/export_test.go b/libgo/go/reflect/export_test.go
index 89473d352a7..bdbd60074ac 100644
--- a/libgo/go/reflect/export_test.go
+++ b/libgo/go/reflect/export_test.go
@@ -6,13 +6,13 @@ package reflect
// MakeRO returns a copy of v with the read-only flag set.
func MakeRO(v Value) Value {
- v.flag |= flagRO
+ v.flag |= flagStickyRO
return v
}
// IsRO reports whether v's read-only flag is set.
func IsRO(v Value) bool {
- return v.flag&flagRO != 0
+ return v.flag&flagStickyRO != 0
}
var CallGC = &callGC
diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go
index e488938a13f..180a364de35 100644
--- a/libgo/go/reflect/type.go
+++ b/libgo/go/reflect/type.go
@@ -516,7 +516,7 @@ func (t *uncommonType) Method(i int) (m Method) {
fl := flag(Func)
if p.pkgPath != nil {
m.PkgPath = *p.pkgPath
- fl |= flagRO
+ fl |= flagStickyRO
}
mt := p.typ
m.Type = toType(mt)
diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go
index a924d8639a2..8374370cfa6 100644
--- a/libgo/go/reflect/value.go
+++ b/libgo/go/reflect/value.go
@@ -44,7 +44,8 @@ type Value struct {
// flag holds metadata about the value.
// The lowest bits are flag bits:
- // - flagRO: obtained via unexported field, so read-only
+ // - flagStickyRO: obtained via unexported not embedded field, so read-only
+ // - flagEmbedRO: obtained via unexported embedded field, so read-only
// - flagIndir: val holds a pointer to the data
// - flagAddr: v.CanAddr is true (implies flagIndir)
// - flagMethod: v is a method value.
@@ -67,12 +68,14 @@ type flag uintptr
const (
flagKindWidth = 5 // there are 27 kinds
flagKindMask flag = 1<<flagKindWidth - 1
- flagRO flag = 1 << 5
- flagIndir flag = 1 << 6
- flagAddr flag = 1 << 7
- flagMethod flag = 1 << 8
- flagMethodFn flag = 1 << 9 // gccgo: first fn parameter is always pointer
- flagMethodShift = 10
+ flagStickyRO flag = 1 << 5
+ flagEmbedRO flag = 1 << 6
+ flagIndir flag = 1 << 7
+ flagAddr flag = 1 << 8
+ flagMethod flag = 1 << 9
+ flagMethodFn flag = 1 << 10 // gccgo: first fn parameter is always pointer
+ flagMethodShift = 11
+ flagRO flag = flagStickyRO | flagEmbedRO
)
func (f flag) kind() Kind {
@@ -617,11 +620,15 @@ func (v Value) Field(i int) Value {
field := &tt.fields[i]
typ := field.typ
- // Inherit permission bits from v.
- fl := v.flag&(flagRO|flagIndir|flagAddr) | flag(typ.Kind())
+ // Inherit permission bits from v, but clear flagEmbedRO.
+ fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
// Using an unexported field forces flagRO.
if field.pkgPath != nil {
- fl |= flagRO
+ if field.name == nil {
+ fl |= flagEmbedRO
+ } else {
+ fl |= flagStickyRO
+ }
}
// Either flagIndir is set and v.ptr points at struct,
// or flagIndir is not set and v.ptr is the actual struct data.
@@ -986,7 +993,7 @@ func (v Value) Method(i int) Value {
if v.typ.Kind() == Interface && v.IsNil() {
panic("reflect: Method on nil interface value")
}
- fl := v.flag & (flagRO | flagIndir)
+ fl := v.flag & (flagStickyRO | flagIndir) // Clear flagEmbedRO
fl |= flag(Func)
fl |= flag(i)<<flagMethodShift | flagMethod
return Value{v.typ, v.ptr, fl}