go/test/fixedbugs/issue24491a.go
Matthew Dempsky 7e2e648a2d cmd/compile/internal/typecheck: normalize go/defer statements earlier
Normalizing go/defer statements to always use functions with zero
parameters and zero results was added to escape analysis, because that
was the earliest point at which all three frontends converged. Now
that we only have the unified frontend, we can do it during typecheck,
which is where we perform all other desugaring and normalization
rewrites.

Change-Id: Iebf7679b117fd78b1dffee2974bbf85ebc923b23
Reviewed-on: https://go-review.googlesource.com/c/go/+/520260
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-08-17 19:36:58 +00:00

97 lines
1.9 KiB
Go

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