diff options
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | libgo/go/encoding/json/decode_test.go | 16 | ||||
-rw-r--r-- | libgo/go/encoding/json/encode.go | 2 | ||||
-rw-r--r-- | libgo/go/encoding/xml/marshal_test.go | 10 | ||||
-rw-r--r-- | libgo/go/encoding/xml/typeinfo.go | 2 | ||||
-rw-r--r-- | libgo/go/reflect/export_test.go | 4 | ||||
-rw-r--r-- | libgo/go/reflect/type.go | 2 | ||||
-rw-r--r-- | libgo/go/reflect/value.go | 29 |
8 files changed, 48 insertions, 19 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index b17ca93..f325bb3 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 8aa158f..51b15ef 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 90782de..e829a93 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 66675d7..ef6c20e 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 22248d2..6766b88 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 89473d3..bdbd600 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 e488938..180a364 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 a924d86..8374370 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} |