// Caller should have already called o.init(n).
Fatalf("%v with unexpected ninit", n.Op)
}
+
+ // Builtin functions.
+ if n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER {
+ n.Left = o.expr(n.Left, nil)
+ n.Right = o.expr(n.Right, nil)
+ o.exprList(n.List)
+ return
+ }
+
+ fixVariadicCall(n)
n.Left = o.expr(n.Left, nil)
- n.Right = o.expr(n.Right, nil) // ODDDARG temp
o.exprList(n.List)
- if n.Op != OCALLFUNC && n.Op != OCALLMETH {
+ if n.Op == OCALLINTER {
return
}
keepAlive := func(arg *Node) {
// Check for "unsafe-uintptr" tag provided by escape analysis.
for i, param := range n.Left.Type.Params().FieldSlice() {
if param.Note == unsafeUintptrTag || param.Note == uintptrEscapesTag {
- if param.IsDDD() && !n.IsDDD() {
- for _, arg := range n.List.Slice()[i:] {
- keepAlive(arg)
+ if arg := n.List.Index(i); arg.Op == OSLICELIT {
+ for _, elt := range arg.List.Slice() {
+ keepAlive(elt)
}
} else {
- keepAlive(n.List.Index(i))
+ keepAlive(arg)
}
}
}
}
case ODDDARG:
- if n.Transient() {
- // The ddd argument does not live beyond the call it is created for.
- // Allocate a temporary that will be cleaned up when this statement
- // completes. We could be more aggressive and try to arrange for it
- // to be cleaned up when the call completes.
- prealloc[n] = o.newTemp(n.Type.Elem(), false)
- }
+ Fatalf("unreachable")
case ODOTTYPE, ODOTTYPE2:
n.Left = o.expr(n.Left, nil)
// fixVariadicCall rewrites calls to variadic functions to use an
// explicit ... argument if one is not already present.
-func fixVariadicCall(call *Node, init *Nodes) {
+func fixVariadicCall(call *Node) {
fntype := call.Left.Type
if !fntype.IsVariadic() || call.IsDDD() {
return
if ddd := call.Right; ddd != nil && slice.Op == OSLICELIT {
slice.Esc = ddd.Esc
- if prealloc[ddd] != nil {
- prealloc[slice] = prealloc[ddd] // temporary to use
- }
+ slice.SetTransient(ddd.Transient())
}
- slice = walkexpr(slice, init)
-
call.List.Set(append(args[:vi], slice))
call.SetIsDDD(true)
}
return // already walked
}
- n.Left = walkexpr(n.Left, init)
- walkexprlist(n.List.Slice(), init)
- fixVariadicCall(n, init)
-
params := n.Left.Type.Params()
args := n.List.Slice()
+ n.Left = walkexpr(n.Left, init)
+ walkexprlist(args, init)
+
// If this is a method call, add the receiver at the beginning of the args.
if n.Op == OCALLMETH {
withRecv := make([]*Node, len(args)+1)