[dev.regabi] cmd/compile: replace CTNIL with ONIL

Properly speaking, "nil" is a zero value, not a constant. So
go/constant does not have a representation for it. To allow replacing
Val with constant.Value, we split out ONIL separately from OLITERAL so
we can get rid of CTNIL.

Passes toolstash-check.

Change-Id: I4c8e60cae3b3c91bbac43b3b0cf2a4ade028d6cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/272650
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthew Dempsky 2020-11-13 20:38:21 -08:00
parent 4af2decf30
commit 88a9e2f9ad
18 changed files with 100 additions and 87 deletions

View file

@ -104,6 +104,9 @@ func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {
s.append(nod(OAS, l, conv(r, l.Type)))
return true
case ONIL:
return true
case OLITERAL:
if isZero(r) {
return true
@ -139,7 +142,7 @@ func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {
e := &p.E[i]
n.Xoffset = l.Xoffset + e.Xoffset
n.Type = e.Expr.Type
if e.Expr.Op == OLITERAL {
if e.Expr.Op == OLITERAL || e.Expr.Op == ONIL {
litsym(n, e.Expr, int(n.Type.Width))
continue
}
@ -171,6 +174,9 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
case ONAME:
return s.staticcopy(l, r)
case ONIL:
return true
case OLITERAL:
if isZero(r) {
return true
@ -232,7 +238,7 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
e := &p.E[i]
n.Xoffset = l.Xoffset + e.Xoffset
n.Type = e.Expr.Type
if e.Expr.Op == OLITERAL {
if e.Expr.Op == OLITERAL || e.Expr.Op == ONIL {
litsym(n, e.Expr, int(n.Type.Width))
continue
}
@ -269,13 +275,14 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
for val.Op == OCONVIFACE {
val = val.Left
}
if val.Type.IsInterface() {
// val is an interface type.
// If val is nil, we can statically initialize l;
// both words are zero and so there no work to do, so report success.
// If val is non-nil, we have no concrete type to record,
// and we won't be able to statically initialize its value, so report failure.
return Isconst(val, CTNIL)
return val.Op == ONIL
}
markTypeUsedInInterface(val.Type, l.Sym.Linksym())
@ -296,7 +303,7 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
// Emit data.
if isdirectiface(val.Type) {
if Isconst(val, CTNIL) {
if val.Op == ONIL {
// Nil is zero, nothing to do.
return true
}
@ -462,7 +469,7 @@ func isStaticCompositeLiteral(n *Node) bool {
}
}
return true
case OLITERAL:
case OLITERAL, ONIL:
return true
case OCONVIFACE:
// See staticassign's OCONVIFACE case for comments.
@ -471,9 +478,9 @@ func isStaticCompositeLiteral(n *Node) bool {
val = val.Left
}
if val.Type.IsInterface() {
return Isconst(val, CTNIL)
return val.Op == ONIL
}
if isdirectiface(val.Type) && Isconst(val, CTNIL) {
if isdirectiface(val.Type) && val.Op == ONIL {
return true
}
return isStaticCompositeLiteral(val)
@ -1105,13 +1112,14 @@ func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n *Node) {
func isZero(n *Node) bool {
switch n.Op {
case ONIL:
return true
case OLITERAL:
switch u := n.Val().U.(type) {
default:
Dump("unexpected literal", n)
Fatalf("isZero")
case *NilVal:
return true
case string:
return u == ""
case bool: