[dev.regabi] cmd/compile: remove CTRUNE

Since CL 255217, we've been able to rely on types.UntypedRune to
identify untyped rune literals, rather than needing Mpint.Rune /
CTRUNE. This makes way for switching to using go/constant, which
doesn't have a separate notion of rune constants distinct from integer
constants.

Passes toolstash-check.

Change-Id: I319861f4758aeea17345c101b167cb307e706a0e
Reviewed-on: https://go-review.googlesource.com/c/go/+/272652
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthew Dempsky 2020-11-13 18:33:19 -08:00
parent 6dae48fb0b
commit c767d73227
7 changed files with 72 additions and 88 deletions

View file

@ -19,7 +19,6 @@ const (
CTxxx Ctype = iota CTxxx Ctype = iota
CTINT CTINT
CTRUNE
CTFLT CTFLT
CTCPLX CTCPLX
CTSTR CTSTR
@ -29,7 +28,7 @@ const (
type Val struct { type Val struct {
// U contains one of: // U contains one of:
// bool bool when Ctype() == CTBOOL // bool bool when Ctype() == CTBOOL
// *Mpint int when Ctype() == CTINT, rune when Ctype() == CTRUNE // *Mpint int when Ctype() == CTINT
// *Mpflt float when Ctype() == CTFLT // *Mpflt float when Ctype() == CTFLT
// *Mpcplx pair of floats when Ctype() == CTCPLX // *Mpcplx pair of floats when Ctype() == CTCPLX
// string string when Ctype() == CTSTR // string string when Ctype() == CTSTR
@ -37,7 +36,7 @@ type Val struct {
} }
func (v Val) Ctype() Ctype { func (v Val) Ctype() Ctype {
switch x := v.U.(type) { switch v.U.(type) {
default: default:
Fatalf("unexpected Ctype for %T", v.U) Fatalf("unexpected Ctype for %T", v.U)
panic("unreachable") panic("unreachable")
@ -46,9 +45,6 @@ func (v Val) Ctype() Ctype {
case bool: case bool:
return CTBOOL return CTBOOL
case *Mpint: case *Mpint:
if x.Rune {
return CTRUNE
}
return CTINT return CTINT
case *Mpflt: case *Mpflt:
return CTFLT return CTFLT
@ -384,7 +380,7 @@ func convertVal(v Val, t *types.Type, explicit bool) Val {
return v return v
} }
case CTINT, CTRUNE: case CTINT:
if explicit && t.IsString() { if explicit && t.IsString() {
return tostr(v) return tostr(v)
} }
@ -449,11 +445,6 @@ func toflt(v Val) Val {
func toint(v Val) Val { func toint(v Val) Val {
switch u := v.U.(type) { switch u := v.U.(type) {
case *Mpint: case *Mpint:
if u.Rune {
i := new(Mpint)
i.Set(u)
v.U = i
}
case *Mpflt: case *Mpflt:
i := new(Mpint) i := new(Mpint)
@ -560,11 +551,7 @@ func consttype(n *Node) Ctype {
} }
func Isconst(n *Node, ct Ctype) bool { func Isconst(n *Node, ct Ctype) bool {
t := consttype(n) return consttype(n) == ct
// If the caller is asking for CTINT, allow CTRUNE too.
// Makes life easier for back ends.
return t == ct || (ct == CTINT && t == CTRUNE)
} }
// evconst rewrites constant expressions into OLITERAL nodes. // evconst rewrites constant expressions into OLITERAL nodes.
@ -710,7 +697,7 @@ func compareOp(x Val, op Op, y Val) bool {
return x != y return x != y
} }
case CTINT, CTRUNE: case CTINT:
x, y := x.U.(*Mpint), y.U.(*Mpint) x, y := x.U.(*Mpint), y.U.(*Mpint)
return cmpZero(x.Cmp(y), op) return cmpZero(x.Cmp(y), op)
@ -784,11 +771,10 @@ Outer:
return Val{U: x || y} return Val{U: x || y}
} }
case CTINT, CTRUNE: case CTINT:
x, y := x.U.(*Mpint), y.U.(*Mpint) x, y := x.U.(*Mpint), y.U.(*Mpint)
u := new(Mpint) u := new(Mpint)
u.Rune = x.Rune || y.Rune
u.Set(x) u.Set(x)
switch op { switch op {
case OADD: case OADD:
@ -879,16 +865,15 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
switch op { switch op {
case OPLUS: case OPLUS:
switch x.Ctype() { switch x.Ctype() {
case CTINT, CTRUNE, CTFLT, CTCPLX: case CTINT, CTFLT, CTCPLX:
return x return x
} }
case ONEG: case ONEG:
switch x.Ctype() { switch x.Ctype() {
case CTINT, CTRUNE: case CTINT:
x := x.U.(*Mpint) x := x.U.(*Mpint)
u := new(Mpint) u := new(Mpint)
u.Rune = x.Rune
u.Set(x) u.Set(x)
u.Neg() u.Neg()
return Val{U: u} return Val{U: u}
@ -912,11 +897,10 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
case OBITNOT: case OBITNOT:
switch x.Ctype() { switch x.Ctype() {
case CTINT, CTRUNE: case CTINT:
x := x.U.(*Mpint) x := x.U.(*Mpint)
u := new(Mpint) u := new(Mpint)
u.Rune = x.Rune
if t.IsSigned() || t.IsUntyped() { if t.IsSigned() || t.IsUntyped() {
// Signed values change sign. // Signed values change sign.
u.SetInt64(-1) u.SetInt64(-1)
@ -937,14 +921,11 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
} }
func shiftOp(x Val, op Op, y Val) Val { func shiftOp(x Val, op Op, y Val) Val {
if x.Ctype() != CTRUNE { x = toint(x)
x = toint(x)
}
y = toint(y) y = toint(y)
u := new(Mpint) u := new(Mpint)
u.Set(x.U.(*Mpint)) u.Set(x.U.(*Mpint))
u.Rune = x.U.(*Mpint).Rune
switch op { switch op {
case OLSH: case OLSH:
u.Lsh(y.U.(*Mpint)) u.Lsh(y.U.(*Mpint))
@ -1010,7 +991,7 @@ func represents(t *types.Type, v Val) bool {
} }
vt := idealType(v.Ctype()) vt := idealType(v.Ctype())
return t == vt return t == vt || (t == types.UntypedRune && vt == types.UntypedInt)
} }
func setboolconst(n *Node, v bool) { func setboolconst(n *Node, v bool) {
@ -1039,8 +1020,6 @@ func idealType(ct Ctype) *types.Type {
return types.UntypedBool return types.UntypedBool
case CTINT: case CTINT:
return types.UntypedInt return types.UntypedInt
case CTRUNE:
return types.UntypedRune
case CTFLT: case CTFLT:
return types.UntypedFloat return types.UntypedFloat
case CTCPLX: case CTCPLX:
@ -1091,31 +1070,30 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
return l, r return l, r
} }
func ctype(t *types.Type) Ctype {
switch t {
case types.UntypedBool:
return CTBOOL
case types.UntypedString:
return CTSTR
case types.UntypedInt:
return CTINT
case types.UntypedRune:
return CTRUNE
case types.UntypedFloat:
return CTFLT
case types.UntypedComplex:
return CTCPLX
}
Fatalf("bad type %v", t)
panic("unreachable")
}
func mixUntyped(t1, t2 *types.Type) *types.Type { func mixUntyped(t1, t2 *types.Type) *types.Type {
t := t1 if t1 == t2 {
if ctype(t2) > ctype(t1) { return t1
t = t2
} }
return t
rank := func(t *types.Type) int {
switch t {
case types.UntypedInt:
return 0
case types.UntypedRune:
return 1
case types.UntypedFloat:
return 2
case types.UntypedComplex:
return 3
}
Fatalf("bad type %v", t)
panic("unreachable")
}
if rank(t2) > rank(t1) {
return t2
}
return t1
} }
func defaultType(t *types.Type) *types.Type { func defaultType(t *types.Type) *types.Type {

View file

@ -526,28 +526,12 @@ func (v Val) Format(s fmt.State, verb rune) {
func (v Val) vconv(s fmt.State, flag FmtFlag) { func (v Val) vconv(s fmt.State, flag FmtFlag) {
switch u := v.U.(type) { switch u := v.U.(type) {
case *Mpint: case *Mpint:
if !u.Rune { if flag&FmtSharp != 0 {
if flag&FmtSharp != 0 { fmt.Fprint(s, u.String())
fmt.Fprint(s, u.String())
return
}
fmt.Fprint(s, u.GoString())
return return
} }
fmt.Fprint(s, u.GoString())
switch x := u.Int64(); { return
case ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'':
fmt.Fprintf(s, "'%c'", int(x))
case 0 <= x && x < 1<<16:
fmt.Fprintf(s, "'\\u%04x'", uint(int(x)))
case 0 <= x && x <= utf8.MaxRune:
fmt.Fprintf(s, "'\\U%08x'", uint64(x))
default:
fmt.Fprintf(s, "('\\x00' + %v)", u)
}
case *Mpflt: case *Mpflt:
if flag&FmtSharp != 0 { if flag&FmtSharp != 0 {
@ -1336,19 +1320,40 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
} }
} }
needUnparen := false
if n.Type != nil && !n.Type.IsUntyped() { if n.Type != nil && !n.Type.IsUntyped() {
// Need parens when type begins with what might // Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-. // be misinterpreted as a unary operator: * or <-.
if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) { if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) {
mode.Fprintf(s, "(%v)(%v)", n.Type, n.Val()) mode.Fprintf(s, "(%v)(", n.Type)
return
} else { } else {
mode.Fprintf(s, "%v(%v)", n.Type, n.Val()) mode.Fprintf(s, "%v(", n.Type)
return
} }
needUnparen = true
} }
mode.Fprintf(s, "%v", n.Val()) if n.Type == types.UntypedRune {
u := n.Val().U.(*Mpint)
switch x := u.Int64(); {
case ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'':
fmt.Fprintf(s, "'%c'", int(x))
case 0 <= x && x < 1<<16:
fmt.Fprintf(s, "'\\u%04x'", uint(int(x)))
case 0 <= x && x <= utf8.MaxRune:
fmt.Fprintf(s, "'\\U%08x'", uint64(x))
default:
fmt.Fprintf(s, "('\\x00' + %v)", u)
}
} else {
mode.Fprintf(s, "%v", n.Val())
}
if needUnparen {
mode.Fprintf(s, ")")
}
// Special case: name used as local variable in export. // Special case: name used as local variable in export.
// _ becomes ~b%d internally; print as _ for export // _ becomes ~b%d internally; print as _ for export

View file

@ -363,7 +363,6 @@ func (p *importReader) value(typ *types.Type) (v Val) {
v.U = p.string() v.U = p.string()
case CTINT: case CTINT:
x := new(Mpint) x := new(Mpint)
x.Rune = typ == types.UntypedRune
p.mpint(&x.Val, typ) p.mpint(&x.Val, typ)
v.U = x v.U = x
case CTFLT: case CTFLT:

View file

@ -13,9 +13,8 @@ import (
// Mpint represents an integer constant. // Mpint represents an integer constant.
type Mpint struct { type Mpint struct {
Val big.Int Val big.Int
Ovf bool // set if Val overflowed compiler limit (sticky) Ovf bool // set if Val overflowed compiler limit (sticky)
Rune bool // set if syntax indicates default type rune
} }
func (a *Mpint) SetOverflow() { func (a *Mpint) SetOverflow() {

View file

@ -656,6 +656,9 @@ func (p *noder) expr(expr syntax.Expr) *Node {
return p.mkname(expr) return p.mkname(expr)
case *syntax.BasicLit: case *syntax.BasicLit:
n := nodlit(p.basicLit(expr)) n := nodlit(p.basicLit(expr))
if expr.Kind == syntax.RuneLit {
n.Type = types.UntypedRune
}
n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error
return n return n
case *syntax.CompositeLit: case *syntax.CompositeLit:
@ -1428,7 +1431,6 @@ func (p *noder) basicLit(lit *syntax.BasicLit) Val {
case syntax.RuneLit: case syntax.RuneLit:
x := new(Mpint) x := new(Mpint)
x.Rune = true
if !lit.Bad { if !lit.Bad {
u, _ := strconv.Unquote(s) u, _ := strconv.Unquote(s)
var r rune var r rune

View file

@ -3724,7 +3724,7 @@ func checkmake(t *types.Type, arg string, np **Node) bool {
// Do range checks for constants before defaultlit // Do range checks for constants before defaultlit
// to avoid redundant "constant NNN overflows int" errors. // to avoid redundant "constant NNN overflows int" errors.
switch consttype(n) { switch consttype(n) {
case CTINT, CTRUNE, CTFLT, CTCPLX: case CTINT, CTFLT, CTCPLX:
v := toint(n.Val()).U.(*Mpint) v := toint(n.Val()).U.(*Mpint)
if v.CmpInt64(0) < 0 { if v.CmpInt64(0) < 0 {
yyerror("negative %s argument in make(%v)", arg, t) yyerror("negative %s argument in make(%v)", arg, t)

View file

@ -1931,10 +1931,11 @@ func walkprint(nn *Node, init *Nodes) *Node {
calls := []*Node{mkcall("printlock", nil, init)} calls := []*Node{mkcall("printlock", nil, init)}
for i, n := range nn.List.Slice() { for i, n := range nn.List.Slice() {
if n.Op == OLITERAL { if n.Op == OLITERAL {
switch n.Val().Ctype() { if n.Type == types.UntypedRune {
case CTRUNE:
n = defaultlit(n, types.Runetype) n = defaultlit(n, types.Runetype)
}
switch n.Val().Ctype() {
case CTINT: case CTINT:
n = defaultlit(n, types.Types[TINT64]) n = defaultlit(n, types.Types[TINT64])