aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/reflect/value.go
diff options
context:
space:
mode:
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}