cmd/compile: more comprehensive tests for #24991
The revised test now checks that unsafe-uintptr correctly works for
variadic uintptr parameters too, and the CL corrects the code so this
code compiles again.
The pointers are still not kept alive properly. That will be fixed by
a followup CL. But this CL at least allows programs not affected by
that to build again.
Updates #24991.
Updates #41460.
Change-Id: If4c39167b6055e602213fb7522c4f527c43ebda9
Reviewed-on: https://go-review.googlesource.com/c/go/+/255877
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go
index 14d2710..4aa2e23 100644
--- a/src/cmd/compile/internal/gc/syntax.go
+++ b/src/cmd/compile/internal/gc/syntax.go
@@ -716,7 +716,7 @@
ODCLCONST // const pi = 3.14
ODCLTYPE // type Int int or type Int = int
- ODELETE // delete(Left, Right)
+ ODELETE // delete(List)
ODOT // Left.Sym (Left is of struct type)
ODOTPTR // Left.Sym (Left is of pointer to struct type)
ODOTMETH // Left.Sym (Left is non-interface, Right is method name)
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 2db352c..933f16d 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3900,6 +3900,7 @@
if !isBuiltinCall {
call.Op = OCALL
call.Left = n.Left
+ call.SetIsDDD(n.IsDDD())
}
call.List.Set(args)
fn.Nbody.Set1(call)
diff --git a/test/fixedbugs/issue24491a.go b/test/fixedbugs/issue24491a.go
index 148134d..3c59579 100644
--- a/test/fixedbugs/issue24491a.go
+++ b/test/fixedbugs/issue24491a.go
@@ -23,29 +23,43 @@
//go:noinline
//go:uintptrescapes
-func test(s string, p uintptr) int {
+func test(s string, p, q uintptr, rest ...uintptr) int {
runtime.GC()
+ runtime.GC()
+
if *(*string)(unsafe.Pointer(p)) != "ok" {
- panic(s + " return unexpected result")
+ panic(s + ": p failed")
}
+ if *(*string)(unsafe.Pointer(q)) != "ok" {
+ panic(s + ": q failed")
+ }
+ for _, r := range rest {
+ // TODO(mdempsky): Remove.
+ break
+
+ 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()))
+ return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
}
func main() {
- test("normal", uintptr(setup()))
+ test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
<-done
- go test("go", uintptr(setup()))
+ go test("go", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
<-done
func() {
- defer test("defer", uintptr(setup()))
+ defer test("defer", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
}()
<-done