diff options
Diffstat (limited to 'test/uintptrescapes3.go')
-rw-r--r-- | test/uintptrescapes3.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/test/uintptrescapes3.go b/test/uintptrescapes3.go new file mode 100644 index 0000000..92be5d1 --- /dev/null +++ b/test/uintptrescapes3.go @@ -0,0 +1,63 @@ +// run + +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that //go:uintptrescapes works for methods. + +package main + +import ( + "fmt" + "runtime" + "unsafe" +) + +var callback func() + +//go:noinline +//go:uintptrescapes +func F(ptr uintptr) { callback() } + +//go:noinline +//go:uintptrescapes +func Fv(ptrs ...uintptr) { callback() } + +type T struct{} + +//go:noinline +//go:uintptrescapes +func (T) M(ptr uintptr) { callback() } + +//go:noinline +//go:uintptrescapes +func (T) Mv(ptrs ...uintptr) { callback() } + +// Each test should pass uintptr(ptr) as an argument to a function call, +// which in turn should call callback. The callback checks that ptr is kept alive. +var tests = []func(ptr unsafe.Pointer){ + func(ptr unsafe.Pointer) { F(uintptr(ptr)) }, + func(ptr unsafe.Pointer) { Fv(uintptr(ptr)) }, + func(ptr unsafe.Pointer) { T{}.M(uintptr(ptr)) }, + func(ptr unsafe.Pointer) { T{}.Mv(uintptr(ptr)) }, +} + +func main() { + for i, test := range tests { + finalized := false + + ptr := new([64]byte) + runtime.SetFinalizer(ptr, func(*[64]byte) { + finalized = true + }) + + callback = func() { + runtime.GC() + if finalized { + fmt.Printf("test #%d failed\n", i) + } + } + test(unsafe.Pointer(ptr)) + } +} |