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// This test makes sure unsafe-uintptr arguments are handled correctly. 8 9package main 10 11import ( 12 "runtime" 13 "unsafe" 14) 15 16var done = make(chan bool, 1) 17 18func setup() unsafe.Pointer { 19 s := "ok" 20 runtime.SetFinalizer(&s, func(p *string) { *p = "FAIL" }) 21 return unsafe.Pointer(&s) 22} 23 24//go:noinline 25//go:uintptrescapes 26func test(s string, p, q uintptr, rest ...uintptr) int { 27 runtime.GC() 28 runtime.GC() 29 30 if *(*string)(unsafe.Pointer(p)) != "ok" { 31 panic(s + ": p failed") 32 } 33 if *(*string)(unsafe.Pointer(q)) != "ok" { 34 panic(s + ": q failed") 35 } 36 for _, r := range rest { 37 if *(*string)(unsafe.Pointer(r)) != "ok" { 38 panic(s + ": r[i] failed") 39 } 40 } 41 42 done <- true 43 return 0 44} 45 46//go:noinline 47func f() int { 48 return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup())) 49} 50 51type S struct{} 52 53//go:noinline 54//go:uintptrescapes 55func (S) test(s string, p, q uintptr, rest ...uintptr) int { 56 return test(s, p, q, rest...) 57} 58 59func main() { 60 test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup())) 61 <-done 62 63 go test("go", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup())) 64 <-done 65 66 func() { 67 defer test("defer", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup())) 68 }() 69 <-done 70 71 func() { 72 for { 73 defer test("defer in for loop", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup())) 74 break 75 } 76 }() 77 <-done 78 79 func() { 80 s := &S{} 81 defer s.test("method call", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup())) 82 }() 83 <-done 84 85 func() { 86 s := &S{} 87 for { 88 defer s.test("defer method loop", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup())) 89 break 90 } 91 }() 92 <-done 93 94 f() 95 <-done 96} 97