diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index dea02077..95a0a100 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -7659,8 +7659,6 @@ func TestAliasNames(t *testing.T) { } } -/* - func TestIssue22031(t *testing.T) { type s []struct{ C int } @@ -7679,6 +7677,8 @@ func TestIssue22031(t *testing.T) { } } +/* + type NonExportedFirst int func (i NonExportedFirst) ΦExported() {} diff --git a/src/reflect/value.go b/src/reflect/value.go index a3b436e4..95a65082 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -20,6 +20,13 @@ const ( valueFlagRO = valueFlagEmbedRO | valueFlagStickyRO ) +func (v valueFlags) ro() valueFlags { + if v&valueFlagRO != 0 { + return valueFlagStickyRO + } + return 0 +} + type Value struct { typecode *rawType value unsafe.Pointer @@ -269,11 +276,11 @@ func (v Value) Addr() Value { if !v.CanAddr() { panic("reflect.Value.Addr of unaddressable value") } - + flags := (v.flags & (valueFlagExported)) | v.flags.ro() return Value{ typecode: pointerTo(v.typecode), value: v.value, - flags: v.flags ^ valueFlagIndirect, + flags: flags, } } @@ -659,10 +666,12 @@ func (v Value) Elem() Value { if ptr == nil { return Value{} } + // Don't copy RO flags + flags := (v.flags & (valueFlagIndirect | valueFlagExported)) | valueFlagIndirect return Value{ typecode: v.typecode.elem(), value: ptr, - flags: v.flags | valueFlagIndirect, + flags: flags, } case Interface: typecode, value := decomposeInterface(*(*interface{})(v.value)) @@ -685,7 +694,6 @@ func (v Value) Field(i int) Value { // Copy flags but clear EmbedRO; we're not an embedded field anymore flags := v.flags & ^valueFlagEmbedRO - if structField.PkgPath != "" { // No PkgPath => not exported. // Clear exported flag even if the parent was exported. @@ -764,9 +772,10 @@ func (v Value) Index(i int) Value { if uint(i) >= uint(slice.len) { panic("reflect: slice index out of range") } + flags := (v.flags & (valueFlagExported | valueFlagIndirect)) | valueFlagIndirect | v.flags.ro() elem := Value{ typecode: v.typecode.elem(), - flags: v.flags | valueFlagIndirect, + flags: flags, } elem.value = unsafe.Add(slice.data, elem.typecode.Size()*uintptr(i)) // pointer to new value return elem