2020-09-08 02:28:43 -06:00
|
|
|
// 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 handled correctly.
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"runtime"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
|
|
|
var done = make(chan bool, 1)
|
|
|
|
|
|
|
|
func setup() unsafe.Pointer {
|
|
|
|
s := "ok"
|
|
|
|
runtime.SetFinalizer(&s, func(p *string) { *p = "FAIL" })
|
|
|
|
return unsafe.Pointer(&s)
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:noinline
|
|
|
|
//go:uintptrescapes
|
2020-09-17 22:38:42 -06:00
|
|
|
func test(s string, p, q uintptr, rest ...uintptr) int {
|
2020-09-08 02:28:43 -06:00
|
|
|
runtime.GC()
|
2020-09-17 22:38:42 -06:00
|
|
|
runtime.GC()
|
|
|
|
|
2020-09-08 02:28:43 -06:00
|
|
|
if *(*string)(unsafe.Pointer(p)) != "ok" {
|
2020-09-17 22:38:42 -06:00
|
|
|
panic(s + ": p failed")
|
|
|
|
}
|
|
|
|
if *(*string)(unsafe.Pointer(q)) != "ok" {
|
|
|
|
panic(s + ": q failed")
|
2020-09-08 02:28:43 -06:00
|
|
|
}
|
2020-09-17 22:38:42 -06:00
|
|
|
for _, r := range rest {
|
|
|
|
if *(*string)(unsafe.Pointer(r)) != "ok" {
|
|
|
|
panic(s + ": r[i] failed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-08 02:28:43 -06:00
|
|
|
done <- true
|
2020-09-11 12:57:27 -06:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:noinline
|
|
|
|
func f() int {
|
2020-09-17 22:38:42 -06:00
|
|
|
return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
2020-09-08 02:28:43 -06:00
|
|
|
}
|
|
|
|
|
2021-02-25 20:17:09 -07:00
|
|
|
type S struct{}
|
|
|
|
|
|
|
|
//go:noinline
|
|
|
|
//go:uintptrescapes
|
|
|
|
func (S) test(s string, p, q uintptr, rest ...uintptr) int {
|
|
|
|
return test(s, p, q, rest...)
|
|
|
|
}
|
|
|
|
|
2020-09-08 02:28:43 -06:00
|
|
|
func main() {
|
2020-09-17 22:38:42 -06:00
|
|
|
test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
2020-09-08 02:28:43 -06:00
|
|
|
<-done
|
|
|
|
|
2020-09-17 22:38:42 -06:00
|
|
|
go test("go", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
2020-09-08 02:28:43 -06:00
|
|
|
<-done
|
|
|
|
|
|
|
|
func() {
|
2020-09-17 22:38:42 -06:00
|
|
|
defer test("defer", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
2020-09-08 02:28:43 -06:00
|
|
|
}()
|
|
|
|
<-done
|
2020-09-11 12:57:27 -06:00
|
|
|
|
2021-02-25 20:17:09 -07:00
|
|
|
func() {
|
|
|
|
for {
|
|
|
|
defer test("defer in for loop", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
<-done
|
|
|
|
func() {
|
|
|
|
s := &S{}
|
|
|
|
defer s.test("method call", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
|
|
|
}()
|
|
|
|
<-done
|
|
|
|
|
|
|
|
func() {
|
|
|
|
s := &S{}
|
|
|
|
for {
|
|
|
|
defer s.test("defer method loop", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
<-done
|
|
|
|
|
2020-09-11 12:57:27 -06:00
|
|
|
f()
|
|
|
|
<-done
|
2020-09-08 02:28:43 -06:00
|
|
|
}
|