1// run 2 3// Copyright 2020 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7//go:build cgo 8 9package main 10 11import ( 12 "runtime/cgo" 13 "unsafe" 14) 15 16type S struct { 17 _ cgo.Incomplete 18 x int 19} 20 21func main() { 22 var i int 23 p := (*S)(unsafe.Pointer(uintptr(unsafe.Pointer(&i)))) 24 v := uintptr(unsafe.Pointer(p)) 25 // p is a pointer to a not-in-heap type. Like some C libraries, 26 // we stored an integer in that pointer. That integer just happens 27 // to be the address of i. 28 // v is also the address of i. 29 // p has a base type which is marked not-in-heap, so it 30 // should not be adjusted when the stack is copied. 31 recurse(100, p, v) 32} 33func recurse(n int, p *S, v uintptr) { 34 if n > 0 { 35 recurse(n-1, p, v) 36 } 37 if uintptr(unsafe.Pointer(p)) != v { 38 panic("adjusted notinheap pointer") 39 } 40} 41