aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/walk.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/walk.go')
-rw-r--r--src/cmd/compile/internal/gc/walk.go21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 98ebb23991..02a7269ff8 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3927,15 +3927,22 @@ func wrapCall(n *Node, init *Nodes) *Node {
}
}
+ wrapArgs := n.List.Slice()
+ // If there's a receiver argument, it needs to be passed through the wrapper too.
+ if n.Op == OCALLMETH || n.Op == OCALLINTER {
+ recv := n.Left.Left
+ wrapArgs = append([]*Node{recv}, wrapArgs...)
+ }
+
// origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
- origArgs := make([]*Node, n.List.Len())
+ origArgs := make([]*Node, len(wrapArgs))
t := nod(OTFUNC, nil, nil)
- for i, arg := range n.List.Slice() {
+ for i, arg := range wrapArgs {
s := lookupN("a", i)
if !isBuiltinCall && arg.Op == OCONVNOP && arg.Type.IsUintptr() && arg.Left.Type.IsUnsafePtr() {
origArgs[i] = arg
arg = arg.Left
- n.List.SetIndex(i, arg)
+ wrapArgs[i] = arg
}
t.List.Append(symfield(s, arg.Type))
}
@@ -3953,6 +3960,12 @@ func wrapCall(n *Node, init *Nodes) *Node {
arg.Type = origArg.Type
args[i] = arg
}
+ if n.Op == OCALLMETH || n.Op == OCALLINTER {
+ // Move wrapped receiver argument back to its appropriate place.
+ recv := typecheck(args[0], ctxExpr)
+ n.Left.Left = recv
+ args = args[1:]
+ }
call := nod(n.Op, nil, nil)
if !isBuiltinCall {
call.Op = OCALL
@@ -3970,7 +3983,7 @@ func wrapCall(n *Node, init *Nodes) *Node {
call = nod(OCALL, nil, nil)
call.Left = fn.Func.Nname
- call.List.Set(n.List.Slice())
+ call.List.Set(wrapArgs)
call = typecheck(call, ctxStmt)
call = walkexpr(call, init)
return call