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