]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/ir: add NewZero
authorMatthew Dempsky <mdempsky@google.com>
Tue, 12 Sep 2023 11:51:16 +0000 (04:51 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 12 Sep 2023 18:53:26 +0000 (18:53 +0000)
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>

src/cmd/compile/internal/ir/const.go
src/cmd/compile/internal/noder/codes.go
src/cmd/compile/internal/noder/helpers.go
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/writer.go

index e2976714490edd149bb3116306cfc5398affad77..0efd1137fe4b9aa3aca9df608d4e3143e33cbca5 100644 (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
index 764d53e9c5849bcf3fd38a75d5bf57dfb425283b..88c10a74e71f98c344e11a671a5341a9e0e99681 100644 (file)
@@ -58,7 +58,7 @@ const (
        exprSizeof
        exprAlignof
        exprOffsetof
-       exprNil
+       exprZero
        exprFuncInst
        exprRecv
        exprReshape
index 05a57d07f049e061d10af27d34b34b4c0fdff861..117abe603d9ee012b8854e38dcd8a1cae4de7444 100644 (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 {
index 2fe593c8e335ea5474e737f46157e087785112ef..760170ddfc7c85d500bbe7173c3180a83f63157c 100644 (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()
index c9162e880aa6cb0e9836fc625115c3c430987373..76c8bb8f2dd0fe03fc65c9828169649393bfe163 100644 (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