| // 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() |
| } |