]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix defer/go calls to variadic unsafe-uintptr functions
authorMatthew Dempsky <mdempsky@google.com>
Sat, 17 Oct 2020 08:10:06 +0000 (01:10 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Sat, 17 Oct 2020 21:30:53 +0000 (21:30 +0000)
Before generating wrapper function, turn any f(a, b, []T{c, d, e}...)
calls back into f(a, b, c, d, e). This allows the existing code for
recognizing and specially handling unsafe.Pointer->uintptr conversions
to correctly handle variadic arguments too.

Fixes #41460.

Change-Id: I0a1255abdd1bd5dafd3e89547aedd4aec878394c
Reviewed-on: https://go-review.googlesource.com/c/go/+/263297
Trust: Matthew Dempsky <mdempsky@google.com>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
src/cmd/compile/internal/gc/walk.go
test/fixedbugs/issue24491a.go

index 05a049b3cc5f19042b4a14c27fc99dfe1378153e..9df288ea653831b1ef59855310fca60ec260221a 100644 (file)
@@ -3881,6 +3881,16 @@ func wrapCall(n *Node, init *Nodes) *Node {
        }
 
        isBuiltinCall := n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER
+
+       // Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e).
+       if !isBuiltinCall && n.IsDDD() {
+               last := n.List.Len() - 1
+               if va := n.List.Index(last); va.Op == OSLICELIT {
+                       n.List.Set(append(n.List.Slice()[:last], va.List.Slice()...))
+                       n.SetIsDDD(false)
+               }
+       }
+
        // origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
        origArgs := make([]*Node, n.List.Len())
        t := nod(OTFUNC, nil, nil)
index 3c595798b58479b4031faa29858c8e546fca494f..8accf8c0a376f0dca01e860560a1b2244c2f62e1 100644 (file)
@@ -34,9 +34,6 @@ func test(s string, p, q uintptr, rest ...uintptr) int {
                panic(s + ": q failed")
        }
        for _, r := range rest {
-               // TODO(mdempsky): Remove.
-               break
-
                if *(*string)(unsafe.Pointer(r)) != "ok" {
                        panic(s + ": r[i] failed")
                }