aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/reflect/value.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2015-11-07 01:24:57 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2015-11-07 01:24:57 +0000
commitf5eb9a8ec6cff02f52d7a29d96ec6641d2a06de1 (patch)
treefb4d9c89c2c9990d67757f795779aa52ee64305c /libgo/go/reflect/value.go
parent39f02a1f52f661a49aa82e878bba152a468f1021 (diff)
downloadgcc-f5eb9a8ec6cff02f52d7a29d96ec6641d2a06de1.zip
gcc-f5eb9a8ec6cff02f52d7a29d96ec6641d2a06de1.tar.gz
gcc-f5eb9a8ec6cff02f52d7a29d96ec6641d2a06de1.tar.bz2
re PR go/66138 (json decoder Decode function fails for some structure return values)
PR go/66138 reflect, encoding/json, encoding/xml: fix unexported embedded structs Bring in three changes from the master Go repository. These changes will be in Go 1.6, but they are appropriate for gccgo now because they resolve a long-standing discrepancy between how gc and gccgo handle the PkgPath field for embedded unexported struct fields. The core issue is described at https://golang.org/cl/7247. This has been reported against gccgo as https://gcc.gnu.org/PR66138. The three changes being brought over are: https://golang.org/cl/14010 reflect: adjust access to unexported embedded structs This CL changes reflect to allow access to exported fields and methods in unexported embedded structs for gccgo and after gc has been adjusted to disallow access to embedded unexported structs. Adresses #12367, #7363, #11007, and #7247. https://golang.org/cl/14011 encoding/json: check for exported fields in embedded structs Addresses issue #12367. https://golang.org/cl/14012 encoding/xml: check for exported fields in embedded structs Addresses issue #12367. Reviewed-on: https://go-review.googlesource.com/16723 From-SVN: r229907
Diffstat (limited to 'libgo/go/reflect/value.go')
-rw-r--r--libgo/go/reflect/value.go29
1 files changed, 18 insertions, 11 deletions
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}