]> Cypherpunks.ru repositories - gostls13.git/blob - test/fixedbugs/issue24491a.go
cmd/compile/internal/typecheck: normalize go/defer statements earlier
[gostls13.git] / test / fixedbugs / issue24491a.go
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
9 package main
10
11 import (
12         "runtime"
13         "unsafe"
14 )
15
16 var done = make(chan bool, 1)
17
18 func 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
26 func 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
47 func f() int {
48         return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
49 }
50
51 type S struct{}
52
53 //go:noinline
54 //go:uintptrescapes
55 func (S) test(s string, p, q uintptr, rest ...uintptr) int {
56         return test(s, p, q, rest...)
57 }
58
59 func 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 }