mirror of
https://github.com/golang/go
synced 2024-11-05 15:56:12 -07:00
cmd/compile/internal/ir: add NewZero
This constructs a zero value of any type, which helps address some corner case scenarios. It should also eventually handle the predeclared "zero" value, at least as currently implemented in go.dev/cl/520336. For #61372. Change-Id: I3a86a94fd8fa388c9c6bf281da8aa532b3da00fc Reviewed-on: https://go-review.googlesource.com/c/go/+/527696 Auto-Submit: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Than McIntosh <thanm@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
661e3be497
commit
c8396b5188
@ -34,6 +34,36 @@ func NewUintptr(pos src.XPos, v int64) Node {
|
||||
return NewBasicLit(pos, types.Types[types.TUINTPTR], constant.MakeInt64(v))
|
||||
}
|
||||
|
||||
// NewZero returns a zero value of the given type.
|
||||
func NewZero(pos src.XPos, typ *types.Type) Node {
|
||||
switch {
|
||||
case typ.HasNil():
|
||||
return NewNilExpr(pos, typ)
|
||||
case typ.IsInteger():
|
||||
return NewBasicLit(pos, typ, intZero)
|
||||
case typ.IsFloat():
|
||||
return NewBasicLit(pos, typ, floatZero)
|
||||
case typ.IsComplex():
|
||||
return NewBasicLit(pos, typ, complexZero)
|
||||
case typ.IsBoolean():
|
||||
return NewBasicLit(pos, typ, constant.MakeBool(false))
|
||||
case typ.IsString():
|
||||
return NewBasicLit(pos, typ, constant.MakeString(""))
|
||||
case typ.IsArray() || typ.IsStruct():
|
||||
// TODO(mdempsky): Return a typechecked expression instead.
|
||||
return NewCompLitExpr(pos, OCOMPLIT, typ, nil)
|
||||
}
|
||||
|
||||
base.FatalfAt(pos, "unexpected type: %v", typ)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
intZero = constant.MakeInt64(0)
|
||||
floatZero = constant.ToFloat(intZero)
|
||||
complexZero = constant.ToComplex(intZero)
|
||||
)
|
||||
|
||||
// NewOne returns an OLITERAL representing 1 with the given type.
|
||||
func NewOne(pos src.XPos, typ *types.Type) Node {
|
||||
var val constant.Value
|
||||
|
@ -58,7 +58,7 @@ const (
|
||||
exprSizeof
|
||||
exprAlignof
|
||||
exprOffsetof
|
||||
exprNil
|
||||
exprZero
|
||||
exprFuncInst
|
||||
exprRecv
|
||||
exprReshape
|
||||
|
@ -59,10 +59,6 @@ func FixValue(typ *types.Type, val constant.Value) constant.Value {
|
||||
return val
|
||||
}
|
||||
|
||||
func Nil(pos src.XPos, typ *types.Type) ir.Node {
|
||||
return ir.NewNilExpr(pos, typ)
|
||||
}
|
||||
|
||||
// Expressions
|
||||
|
||||
func Addr(pos src.XPos, x ir.Node) *ir.AddrExpr {
|
||||
|
@ -1340,16 +1340,9 @@ func (r *reader) syntheticArgs(pos src.XPos) (recvs, params ir.Nodes) {
|
||||
// For anonymous and blank parameters, we don't have an *ir.Name
|
||||
// to use as the argument. However, since we know the shaped
|
||||
// function won't use the value either, we can just pass the
|
||||
// zero value. (Also unfortunately, we don't have an easy
|
||||
// zero-value IR node; so we use a default-initialized temporary
|
||||
// variable.)
|
||||
// zero value.
|
||||
if arg == nil {
|
||||
tmp := typecheck.TempAt(pos, r.curfn, param.Type)
|
||||
r.curfn.Body.Append(
|
||||
typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)),
|
||||
typecheck.Stmt(ir.NewAssignStmt(pos, tmp, nil)),
|
||||
)
|
||||
arg = tmp
|
||||
arg = ir.NewZero(pos, param.Type)
|
||||
}
|
||||
|
||||
out.Append(arg)
|
||||
@ -2177,10 +2170,10 @@ func (r *reader) expr() (res ir.Node) {
|
||||
val := FixValue(typ, r.Value())
|
||||
return ir.NewBasicLit(pos, typ, val)
|
||||
|
||||
case exprNil:
|
||||
case exprZero:
|
||||
pos := r.pos()
|
||||
typ := r.typ()
|
||||
return Nil(pos, typ)
|
||||
return ir.NewZero(pos, typ)
|
||||
|
||||
case exprCompLit:
|
||||
return r.compLit()
|
||||
|
@ -1752,7 +1752,7 @@ func (w *writer) expr(expr syntax.Expr) {
|
||||
}
|
||||
|
||||
if _, isNil := obj.(*types2.Nil); isNil {
|
||||
w.Code(exprNil)
|
||||
w.Code(exprZero)
|
||||
w.pos(expr)
|
||||
w.typ(tv.Type)
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user