diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index fcd0e15f0a..922998125b 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -7721,6 +7721,8 @@ func TestNotInHeapDeref(t *testing.T) { v = ValueOf((*nih)(unsafe.Pointer(new(int)))) shouldPanic("reflect: reflect.Value.Elem on an invalid notinheap pointer", func() { v.Elem() }) + shouldPanic("reflect: reflect.Value.Pointer on an invalid notinheap pointer", func() { v.Pointer() }) + shouldPanic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer", func() { v.UnsafePointer() }) } func TestMethodCallValueCodePtr(t *testing.T) { diff --git a/src/reflect/value.go b/src/reflect/value.go index 7bb8ae5b97..3e723e82a4 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -1940,11 +1940,13 @@ func (v Value) Pointer() uintptr { switch k { case Ptr: if v.typ.ptrdata == 0 { - // Handle pointers to go:notinheap types directly, - // so we never materialize such pointers as an - // unsafe.Pointer. (Such pointers are always indirect.) - // See issue 42076. - return *(*uintptr)(v.ptr) + val := *(*uintptr)(v.ptr) + // Since it is a not-in-heap pointer, all pointers to the heap are + // forbidden! See comment in Value.Elem and issue #48399. + if !verifyNotInHeapPtr(val) { + panic("reflect: reflect.Value.Pointer on an invalid notinheap pointer") + } + return val } fallthrough case Chan, Map, UnsafePointer: