summaryrefslogtreecommitdiffstats
path: root/test/fixedbugs/issue24491a.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--test/fixedbugs/issue24491a.go96
1 files changed, 96 insertions, 0 deletions
diff --git a/test/fixedbugs/issue24491a.go b/test/fixedbugs/issue24491a.go
new file mode 100644
index 0000000..d30b65b
--- /dev/null
+++ b/test/fixedbugs/issue24491a.go
@@ -0,0 +1,96 @@
+// 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
+func test(s string, p, q uintptr, rest ...uintptr) int {
+ runtime.GC()
+ runtime.GC()
+
+ if *(*string)(unsafe.Pointer(p)) != "ok" {
+ panic(s + ": p failed")
+ }
+ if *(*string)(unsafe.Pointer(q)) != "ok" {
+ panic(s + ": q failed")
+ }
+ for _, r := range rest {
+ if *(*string)(unsafe.Pointer(r)) != "ok" {
+ panic(s + ": r[i] failed")
+ }
+ }
+
+ done <- true
+ return 0
+}
+
+//go:noinline
+func f() int {
+ return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
+}
+
+type S struct{}
+
+//go:noinline
+//go:uintptrescapes
+func (S) test(s string, p, q uintptr, rest ...uintptr) int {
+ return test(s, p, q, rest...)
+}
+
+func main() {
+ test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
+ <-done
+
+ go test("go", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
+ <-done
+
+ func() {
+ defer test("defer", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
+ }()
+ <-done
+
+ 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
+
+ f()
+ <-done
+}