if !types.Identical(t, x.Type()) {
panic("dotdotdot base type does not match order's assigned type")
}
- a = initStackTemp(init, x, vstat != nil)
+ a = initStackTemp(init, x, vstat)
} else if n.Esc() == ir.EscNone {
- if vstat == nil {
- // TODO(mdempsky): Remove this useless temporary.
- // It's only needed to keep toolstash happy.
- typecheck.Temp(t)
- }
- a = initStackTemp(init, typecheck.Temp(t), vstat != nil)
+ a = initStackTemp(init, typecheck.Temp(t), vstat)
} else {
a = ir.NewUnaryExpr(base.Pos, ir.ONEW, ir.TypeNode(t))
}
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, vauto, a))
- if vstat != nil {
- // copy static to heap (4)
+ if vstat != nil && n.Prealloc == nil && n.Esc() != ir.EscNone {
+ // If we allocated on the heap with ONEW, copy the static to the
+ // heap (4). We skip this for stack temporaries, because
+ // initStackTemp already handled the copy.
a = ir.NewStarExpr(base.Pos, vauto)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, a, vstat))
}
var r ir.Node
if n.Prealloc != nil {
// n.Prealloc is stack temporary used as backing store.
- r = initStackTemp(init, n.Prealloc, false)
+ r = initStackTemp(init, n.Prealloc, nil)
} else {
r = ir.NewUnaryExpr(base.Pos, ir.ONEW, ir.TypeNode(n.X.Type()))
r.SetEsc(n.Esc())
)
// initStackTemp appends statements to init to initialize the given
-// temporary variable, and then returns the expression &tmp. If vardef
-// is true, then the variable is initialized with OVARDEF, and the
-// caller must ensure the variable is later assigned before use;
-// otherwise, it's zero initialized.
-//
-// TODO(mdempsky): Change callers to provide tmp's initial value,
-// rather than just vardef, to make this safer/easier to use.
-func initStackTemp(init *ir.Nodes, tmp *ir.Name, vardef bool) *ir.AddrExpr {
- if vardef {
- init.Append(ir.NewUnaryExpr(base.Pos, ir.OVARDEF, tmp))
- } else {
- appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmp, nil))
+// temporary variable to val, and then returns the expression &tmp.
+func initStackTemp(init *ir.Nodes, tmp *ir.Name, val ir.Node) *ir.AddrExpr {
+ if val != nil && !types.Identical(tmp.Type(), val.Type()) {
+ base.Fatalf("bad initial value for %L: %L", tmp, val)
}
+ appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmp, val))
return typecheck.Expr(typecheck.NodAddr(tmp)).(*ir.AddrExpr)
}
// allocated temporary variable of the given type. Statements to
// zero-initialize tmp are appended to init.
func stackTempAddr(init *ir.Nodes, typ *types.Type) *ir.AddrExpr {
- return initStackTemp(init, typecheck.Temp(typ), false)
+ return initStackTemp(init, typecheck.Temp(typ), nil)
}
// stackBufAddr returns thte expression &tmp, where tmp is a newly