| // run | |
| // Copyright 2020 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. | |
| // This test makes sure unsafe-uintptr arguments are not | |
| // kept alive longer than expected. | |
| package main | |
| import ( | |
| "runtime" | |
| "unsafe" | |
| ) | |
| var done = make(chan bool) | |
| func setup() unsafe.Pointer { | |
| s := "ok" | |
| runtime.SetFinalizer(&s, func(p *string) { close(done) }) | |
| return unsafe.Pointer(&s) | |
| } | |
| //go:noinline | |
| //go:uintptrescapes | |
| func before(p uintptr) int { | |
| runtime.GC() | |
| select { | |
| case <-done: | |
| panic("GC early") | |
| default: | |
| } | |
| return 0 | |
| } | |
| func after() int { | |
| runtime.GC() | |
| runtime.GC() | |
| <-done | |
| return 0 | |
| } | |
| func main() { | |
| _ = before(uintptr(setup())) + after() | |
| } |