1
0
mirror of https://github.com/golang/go synced 2024-11-18 13:54:59 -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:
Matthew Dempsky 2023-09-12 04:51:16 -07:00
parent 661e3be497
commit c8396b5188
5 changed files with 36 additions and 17 deletions

View File

@ -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

View File

@ -58,7 +58,7 @@ const (
exprSizeof
exprAlignof
exprOffsetof
exprNil
exprZero
exprFuncInst
exprRecv
exprReshape

View File

@ -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 {

View File

@ -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()

View File

@ -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