[dev.regabi] cmd/compile: prep refactoring for switching to go/constant

This CL replaces gc.Ctype (along with its CTINT, etc. constants) with
constant.Kind; renames Val.Ctype to Val.Kind; and replaces a handful
of abstraction-violating patterns that can be readily expressed
differently.

The next commit will actually replace Val with constant.Value.

Passes toolstash-check.

[git-generate]
cd src/cmd/compile/internal/gc

sed -i 's/type Ctype uint8/type Ctype = constant.Kind/' const.go
goimports -w const.go

rf '
inline -rm Ctype
mv Val.Ctype Val.Kind

ex import "go/constant"; \
  CTxxx  -> constant.Unknown; \
  CTINT  -> constant.Int; \
  CTFLT  -> constant.Float; \
  CTCPLX -> constant.Complex; \
  CTBOOL -> constant.Bool; \
  CTSTR  -> constant.String

rm CTxxx CTINT CTFLT CTCPLX CTBOOL CTSTR

ex import "cmd/compile/internal/types"; \
  var t *types.Type; \
  var v, v2 Val; \
  v.U.(*Mpint).Cmp(maxintval[TINT]) > 0 -> doesoverflow(v, types.Types[TINT]); \
  v.U.(*Mpint).Cmp(v2.U.(*Mpint)) > 0 -> compareOp(v, OGT, v2); \
  maxintval[t.Etype].Cmp(maxintval[TUINT]) <= 0 -> t.Size() <= types.Types[TUINT].Size(); \
  maxintval[t.Etype].Cmp(maxintval[TUINT]) >  0 -> t.Size() >  types.Types[TUINT].Size();
'

go test cmd/compile -u

Change-Id: I6c22ec0597508845f88eee639a0d76cbaa66d08f
Reviewed-on: https://go-review.googlesource.com/c/go/+/272653
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-23 13:42:43 -08:00
parent 015423a15b
commit 742c05e3bc
14 changed files with 153 additions and 154 deletions

View file

@ -85,8 +85,6 @@ var knownFormats = map[string]string{
"cmd/compile/internal/gc.Class %d": "", "cmd/compile/internal/gc.Class %d": "",
"cmd/compile/internal/gc.Class %s": "", "cmd/compile/internal/gc.Class %s": "",
"cmd/compile/internal/gc.Class %v": "", "cmd/compile/internal/gc.Class %v": "",
"cmd/compile/internal/gc.Ctype %d": "",
"cmd/compile/internal/gc.Ctype %v": "",
"cmd/compile/internal/gc.Nodes %#v": "", "cmd/compile/internal/gc.Nodes %#v": "",
"cmd/compile/internal/gc.Nodes %+v": "", "cmd/compile/internal/gc.Nodes %+v": "",
"cmd/compile/internal/gc.Nodes %.v": "", "cmd/compile/internal/gc.Nodes %.v": "",
@ -138,6 +136,8 @@ var knownFormats = map[string]string{
"float64 %.3f": "", "float64 %.3f": "",
"float64 %.6g": "", "float64 %.6g": "",
"float64 %g": "", "float64 %g": "",
"go/constant.Kind %d": "",
"go/constant.Kind %v": "",
"int %#x": "", "int %#x": "",
"int %-12d": "", "int %-12d": "",
"int %-6d": "", "int %-6d": "",

View file

@ -8,23 +8,11 @@ import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/src" "cmd/internal/src"
"fmt" "fmt"
"go/constant"
"math/big" "math/big"
"strings" "strings"
) )
// Ctype describes the constant kind of an "ideal" (untyped) constant.
type Ctype uint8
const (
CTxxx Ctype = iota
CTINT
CTFLT
CTCPLX
CTSTR
CTBOOL
)
type Val struct { type Val struct {
// U contains one of: // U contains one of:
// bool bool when Ctype() == CTBOOL // bool bool when Ctype() == CTBOOL
@ -35,28 +23,28 @@ type Val struct {
U interface{} U interface{}
} }
func (v Val) Ctype() Ctype { func (v Val) Kind() constant.Kind {
switch 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")
case nil: case nil:
return CTxxx return constant.Unknown
case bool: case bool:
return CTBOOL return constant.Bool
case *Mpint: case *Mpint:
return CTINT return constant.Int
case *Mpflt: case *Mpflt:
return CTFLT return constant.Float
case *Mpcplx: case *Mpcplx:
return CTCPLX return constant.Complex
case string: case string:
return CTSTR return constant.String
} }
} }
func eqval(a, b Val) bool { func eqval(a, b Val) bool {
if a.Ctype() != b.Ctype() { if a.Kind() != b.Kind() {
return false return false
} }
switch x := a.U.(type) { switch x := a.U.(type) {
@ -103,7 +91,7 @@ func (v Val) Interface() interface{} {
// Int64Val returns n as an int64. // Int64Val returns n as an int64.
// n must be an integer or rune constant. // n must be an integer or rune constant.
func (n *Node) Int64Val() int64 { func (n *Node) Int64Val() int64 {
if !Isconst(n, CTINT) { if !Isconst(n, constant.Int) {
Fatalf("Int64Val(%v)", n) Fatalf("Int64Val(%v)", n)
} }
return n.Val().U.(*Mpint).Int64() return n.Val().U.(*Mpint).Int64()
@ -111,7 +99,7 @@ func (n *Node) Int64Val() int64 {
// CanInt64 reports whether it is safe to call Int64Val() on n. // CanInt64 reports whether it is safe to call Int64Val() on n.
func (n *Node) CanInt64() bool { func (n *Node) CanInt64() bool {
if !Isconst(n, CTINT) { if !Isconst(n, constant.Int) {
return false return false
} }
@ -123,7 +111,7 @@ func (n *Node) CanInt64() bool {
// BoolVal returns n as a bool. // BoolVal returns n as a bool.
// n must be a boolean constant. // n must be a boolean constant.
func (n *Node) BoolVal() bool { func (n *Node) BoolVal() bool {
if !Isconst(n, CTBOOL) { if !Isconst(n, constant.Bool) {
Fatalf("BoolVal(%v)", n) Fatalf("BoolVal(%v)", n)
} }
return n.Val().U.(bool) return n.Val().U.(bool)
@ -132,7 +120,7 @@ func (n *Node) BoolVal() bool {
// StringVal returns the value of a literal string Node as a string. // StringVal returns the value of a literal string Node as a string.
// n must be a string constant. // n must be a string constant.
func (n *Node) StringVal() string { func (n *Node) StringVal() string {
if !Isconst(n, CTSTR) { if !Isconst(n, constant.String) {
Fatalf("StringVal(%v)", n) Fatalf("StringVal(%v)", n)
} }
return n.Val().U.(string) return n.Val().U.(string)
@ -369,23 +357,23 @@ func operandType(op Op, t *types.Type) *types.Type {
// If explicit is true, then conversions from integer to string are // If explicit is true, then conversions from integer to string are
// also allowed. // also allowed.
func convertVal(v Val, t *types.Type, explicit bool) Val { func convertVal(v Val, t *types.Type, explicit bool) Val {
switch ct := v.Ctype(); ct { switch ct := v.Kind(); ct {
case CTBOOL: case constant.Bool:
if t.IsBoolean() { if t.IsBoolean() {
return v return v
} }
case CTSTR: case constant.String:
if t.IsString() { if t.IsString() {
return v return v
} }
case CTINT: case constant.Int:
if explicit && t.IsString() { if explicit && t.IsString() {
return tostr(v) return tostr(v)
} }
fallthrough fallthrough
case CTFLT, CTCPLX: case constant.Float, constant.Complex:
switch { switch {
case t.IsInteger(): case t.IsInteger():
v = toint(v) v = toint(v)
@ -543,14 +531,14 @@ func tostr(v Val) Val {
return v return v
} }
func consttype(n *Node) Ctype { func consttype(n *Node) constant.Kind {
if n == nil || n.Op != OLITERAL { if n == nil || n.Op != OLITERAL {
return CTxxx return constant.Unknown
} }
return n.Val().Ctype() return n.Val().Kind()
} }
func Isconst(n *Node, ct Ctype) bool { func Isconst(n *Node, ct constant.Kind) bool {
return consttype(n) == ct return consttype(n) == ct
} }
@ -596,11 +584,11 @@ func evconst(n *Node) {
// Merge adjacent constants in the argument list. // Merge adjacent constants in the argument list.
s := n.List.Slice() s := n.List.Slice()
for i1 := 0; i1 < len(s); i1++ { for i1 := 0; i1 < len(s); i1++ {
if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) { if Isconst(s[i1], constant.String) && i1+1 < len(s) && Isconst(s[i1+1], constant.String) {
// merge from i1 up to but not including i2 // merge from i1 up to but not including i2
var strs []string var strs []string
i2 := i1 i2 := i1
for i2 < len(s) && Isconst(s[i2], CTSTR) { for i2 < len(s) && Isconst(s[i2], constant.String) {
strs = append(strs, s[i2].StringVal()) strs = append(strs, s[i2].StringVal())
i2++ i2++
} }
@ -613,7 +601,7 @@ func evconst(n *Node) {
} }
} }
if len(s) == 1 && Isconst(s[0], CTSTR) { if len(s) == 1 && Isconst(s[0], constant.String) {
n.Op = OLITERAL n.Op = OLITERAL
n.SetVal(s[0].Val()) n.SetVal(s[0].Val())
} else { } else {
@ -623,7 +611,7 @@ func evconst(n *Node) {
case OCAP, OLEN: case OCAP, OLEN:
switch nl.Type.Etype { switch nl.Type.Etype {
case TSTRING: case TSTRING:
if Isconst(nl, CTSTR) { if Isconst(nl, constant.String) {
setintconst(n, int64(len(nl.StringVal()))) setintconst(n, int64(len(nl.StringVal())))
} }
case TARRAY: case TARRAY:
@ -674,9 +662,9 @@ func evconst(n *Node) {
func match(x, y Val) (Val, Val) { func match(x, y Val) (Val, Val) {
switch { switch {
case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX: case x.Kind() == constant.Complex || y.Kind() == constant.Complex:
return tocplx(x), tocplx(y) return tocplx(x), tocplx(y)
case x.Ctype() == CTFLT || y.Ctype() == CTFLT: case x.Kind() == constant.Float || y.Kind() == constant.Float:
return toflt(x), toflt(y) return toflt(x), toflt(y)
} }
@ -687,8 +675,8 @@ func match(x, y Val) (Val, Val) {
func compareOp(x Val, op Op, y Val) bool { func compareOp(x Val, op Op, y Val) bool {
x, y = match(x, y) x, y = match(x, y)
switch x.Ctype() { switch x.Kind() {
case CTBOOL: case constant.Bool:
x, y := x.U.(bool), y.U.(bool) x, y := x.U.(bool), y.U.(bool)
switch op { switch op {
case OEQ: case OEQ:
@ -697,15 +685,15 @@ func compareOp(x Val, op Op, y Val) bool {
return x != y return x != y
} }
case CTINT: case constant.Int:
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)
case CTFLT: case constant.Float:
x, y := x.U.(*Mpflt), y.U.(*Mpflt) x, y := x.U.(*Mpflt), y.U.(*Mpflt)
return cmpZero(x.Cmp(y), op) return cmpZero(x.Cmp(y), op)
case CTCPLX: case constant.Complex:
x, y := x.U.(*Mpcplx), y.U.(*Mpcplx) x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0 eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
switch op { switch op {
@ -715,7 +703,7 @@ func compareOp(x Val, op Op, y Val) bool {
return !eq return !eq
} }
case CTSTR: case constant.String:
x, y := x.U.(string), y.U.(string) x, y := x.U.(string), y.U.(string)
switch op { switch op {
case OEQ: case OEQ:
@ -761,8 +749,8 @@ func binaryOp(x Val, op Op, y Val) Val {
x, y = match(x, y) x, y = match(x, y)
Outer: Outer:
switch x.Ctype() { switch x.Kind() {
case CTBOOL: case constant.Bool:
x, y := x.U.(bool), y.U.(bool) x, y := x.U.(bool), y.U.(bool)
switch op { switch op {
case OANDAND: case OANDAND:
@ -771,7 +759,7 @@ Outer:
return Val{U: x || y} return Val{U: x || y}
} }
case CTINT: case constant.Int:
x, y := x.U.(*Mpint), y.U.(*Mpint) x, y := x.U.(*Mpint), y.U.(*Mpint)
u := new(Mpint) u := new(Mpint)
@ -808,7 +796,7 @@ Outer:
} }
return Val{U: u} return Val{U: u}
case CTFLT: case constant.Float:
x, y := x.U.(*Mpflt), y.U.(*Mpflt) x, y := x.U.(*Mpflt), y.U.(*Mpflt)
u := newMpflt() u := newMpflt()
@ -831,7 +819,7 @@ Outer:
} }
return Val{U: u} return Val{U: u}
case CTCPLX: case constant.Complex:
x, y := x.U.(*Mpcplx), y.U.(*Mpcplx) x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
u := newMpcmplx() u := newMpcmplx()
@ -864,28 +852,28 @@ Outer:
func unaryOp(op Op, x Val, t *types.Type) Val { func unaryOp(op Op, x Val, t *types.Type) Val {
switch op { switch op {
case OPLUS: case OPLUS:
switch x.Ctype() { switch x.Kind() {
case CTINT, CTFLT, CTCPLX: case constant.Int, constant.Float, constant.Complex:
return x return x
} }
case ONEG: case ONEG:
switch x.Ctype() { switch x.Kind() {
case CTINT: case constant.Int:
x := x.U.(*Mpint) x := x.U.(*Mpint)
u := new(Mpint) u := new(Mpint)
u.Set(x) u.Set(x)
u.Neg() u.Neg()
return Val{U: u} return Val{U: u}
case CTFLT: case constant.Float:
x := x.U.(*Mpflt) x := x.U.(*Mpflt)
u := newMpflt() u := newMpflt()
u.Set(x) u.Set(x)
u.Neg() u.Neg()
return Val{U: u} return Val{U: u}
case CTCPLX: case constant.Complex:
x := x.U.(*Mpcplx) x := x.U.(*Mpcplx)
u := newMpcmplx() u := newMpcmplx()
u.Real.Set(&x.Real) u.Real.Set(&x.Real)
@ -896,8 +884,8 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
} }
case OBITNOT: case OBITNOT:
switch x.Ctype() { switch x.Kind() {
case CTINT: case constant.Int:
x := x.U.(*Mpint) x := x.U.(*Mpint)
u := new(Mpint) u := new(Mpint)
@ -967,12 +955,12 @@ func setconst(n *Node, v Val) {
lineno = lno lineno = lno
if !n.Type.IsUntyped() { if !n.Type.IsUntyped() {
switch v.Ctype() { switch v.Kind() {
// Truncate precision for non-ideal float. // Truncate precision for non-ideal float.
case CTFLT: case constant.Float:
n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)})
// Truncate precision for non-ideal complex. // Truncate precision for non-ideal complex.
case CTCPLX: case constant.Complex:
n.SetVal(Val{trunccmplxlit(v.U.(*Mpcplx), n.Type)}) n.SetVal(Val{trunccmplxlit(v.U.(*Mpcplx), n.Type)})
} }
} }
@ -990,7 +978,7 @@ func represents(t *types.Type, v Val) bool {
return true return true
} }
vt := idealType(v.Ctype()) vt := idealType(v.Kind())
return t == vt || (t == types.UntypedRune && vt == types.UntypedInt) return t == vt || (t == types.UntypedRune && vt == types.UntypedInt)
} }
@ -1007,22 +995,22 @@ func setintconst(n *Node, v int64) {
// nodlit returns a new untyped constant with value v. // nodlit returns a new untyped constant with value v.
func nodlit(v Val) *Node { func nodlit(v Val) *Node {
n := nod(OLITERAL, nil, nil) n := nod(OLITERAL, nil, nil)
n.Type = idealType(v.Ctype()) n.Type = idealType(v.Kind())
n.SetVal(v) n.SetVal(v)
return n return n
} }
func idealType(ct Ctype) *types.Type { func idealType(ct constant.Kind) *types.Type {
switch ct { switch ct {
case CTSTR: case constant.String:
return types.UntypedString return types.UntypedString
case CTBOOL: case constant.Bool:
return types.UntypedBool return types.UntypedBool
case CTINT: case constant.Int:
return types.UntypedInt return types.UntypedInt
case CTFLT: case constant.Float:
return types.UntypedFloat return types.UntypedFloat
case CTCPLX: case constant.Complex:
return types.UntypedComplex return types.UntypedComplex
} }
Fatalf("unexpected Ctype: %v", ct) Fatalf("unexpected Ctype: %v", ct)
@ -1121,7 +1109,7 @@ func defaultType(t *types.Type) *types.Type {
} }
func smallintconst(n *Node) bool { func smallintconst(n *Node) bool {
if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { if n.Op == OLITERAL && Isconst(n, constant.Int) && n.Type != nil {
switch simtype[n.Type.Etype] { switch simtype[n.Type.Etype] {
case TINT8, case TINT8,
TUINT8, TUINT8,

View file

@ -10,6 +10,7 @@ import (
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/src" "cmd/internal/src"
"fmt" "fmt"
"go/constant"
"strings" "strings"
) )
@ -637,7 +638,7 @@ func interfacefield(n *Node) *types.Field {
Fatalf("interfacefield: oops %v\n", n) Fatalf("interfacefield: oops %v\n", n)
} }
if n.Val().Ctype() != CTxxx { if n.Val().Kind() != constant.Unknown {
yyerror("interface method cannot have annotation") yyerror("interface method cannot have annotation")
} }

View file

@ -9,6 +9,7 @@ import (
"cmd/internal/bio" "cmd/internal/bio"
"cmd/internal/src" "cmd/internal/src"
"fmt" "fmt"
"go/constant"
) )
var ( var (
@ -208,8 +209,8 @@ func dumpasmhdr() {
} }
switch n.Op { switch n.Op {
case OLITERAL: case OLITERAL:
t := n.Val().Ctype() t := n.Val().Kind()
if t == CTFLT || t == CTCPLX { if t == constant.Float || t == constant.Complex {
break break
} }
fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val()) fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val())

View file

@ -556,7 +556,7 @@ func (v Val) vconv(s fmt.State, flag FmtFlag) {
fmt.Fprint(s, u) fmt.Fprint(s, u)
default: default:
fmt.Fprintf(s, "<ctype=%d>", v.Ctype()) fmt.Fprintf(s, "<ctype=%d>", v.Kind())
} }
} }

View file

@ -210,6 +210,7 @@ import (
"crypto/md5" "crypto/md5"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"go/constant"
"io" "io"
"math/big" "math/big"
"sort" "sort"
@ -748,28 +749,28 @@ func (w *exportWriter) param(f *types.Field) {
w.typ(f.Type) w.typ(f.Type)
} }
func constTypeOf(typ *types.Type) Ctype { func constTypeOf(typ *types.Type) constant.Kind {
switch typ { switch typ {
case types.UntypedInt, types.UntypedRune: case types.UntypedInt, types.UntypedRune:
return CTINT return constant.Int
case types.UntypedFloat: case types.UntypedFloat:
return CTFLT return constant.Float
case types.UntypedComplex: case types.UntypedComplex:
return CTCPLX return constant.Complex
} }
switch typ.Etype { switch typ.Etype {
case TBOOL: case TBOOL:
return CTBOOL return constant.Bool
case TSTRING: case TSTRING:
return CTSTR return constant.String
case TINT, TINT8, TINT16, TINT32, TINT64, case TINT, TINT8, TINT16, TINT32, TINT64,
TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR: TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR:
return CTINT return constant.Int
case TFLOAT32, TFLOAT64: case TFLOAT32, TFLOAT64:
return CTFLT return constant.Float
case TCOMPLEX64, TCOMPLEX128: case TCOMPLEX64, TCOMPLEX128:
return CTCPLX return constant.Complex
} }
Fatalf("unexpected constant type: %v", typ) Fatalf("unexpected constant type: %v", typ)
@ -786,15 +787,15 @@ func (w *exportWriter) value(typ *types.Type, v Val) {
// and provides a useful consistency check. // and provides a useful consistency check.
switch constTypeOf(typ) { switch constTypeOf(typ) {
case CTBOOL: case constant.Bool:
w.bool(v.U.(bool)) w.bool(v.U.(bool))
case CTSTR: case constant.String:
w.string(v.U.(string)) w.string(v.U.(string))
case CTINT: case constant.Int:
w.mpint(&v.U.(*Mpint).Val, typ) w.mpint(&v.U.(*Mpint).Val, typ)
case CTFLT: case constant.Float:
w.mpfloat(&v.U.(*Mpflt).Val, typ) w.mpfloat(&v.U.(*Mpflt).Val, typ)
case CTCPLX: case constant.Complex:
x := v.U.(*Mpcplx) x := v.U.(*Mpcplx)
w.mpfloat(&x.Real.Val, typ) w.mpfloat(&x.Real.Val, typ)
w.mpfloat(&x.Imag.Val, typ) w.mpfloat(&x.Imag.Val, typ)

View file

@ -15,6 +15,7 @@ import (
"cmd/internal/src" "cmd/internal/src"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"go/constant"
"io" "io"
"math/big" "math/big"
"os" "os"
@ -357,19 +358,19 @@ func (r *importReader) doDecl(n *Node) {
func (p *importReader) value(typ *types.Type) (v Val) { func (p *importReader) value(typ *types.Type) (v Val) {
switch constTypeOf(typ) { switch constTypeOf(typ) {
case CTBOOL: case constant.Bool:
v.U = p.bool() v.U = p.bool()
case CTSTR: case constant.String:
v.U = p.string() v.U = p.string()
case CTINT: case constant.Int:
x := new(Mpint) x := new(Mpint)
p.mpint(&x.Val, typ) p.mpint(&x.Val, typ)
v.U = x v.U = x
case CTFLT: case constant.Float:
x := newMpflt() x := newMpflt()
p.float(x, typ) p.float(x, typ)
v.U = x v.U = x
case CTCPLX: case constant.Complex:
x := newMpcmplx() x := newMpcmplx()
p.float(&x.Real, typ) p.float(&x.Real, typ)
p.float(&x.Imag, typ) p.float(&x.Imag, typ)

View file

@ -32,6 +32,7 @@ import (
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/src" "cmd/internal/src"
"fmt" "fmt"
"go/constant"
"strings" "strings"
) )
@ -417,7 +418,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
} }
case OIF: case OIF:
if Isconst(n.Left, CTBOOL) { if Isconst(n.Left, constant.Bool) {
// This if and the condition cost nothing. // This if and the condition cost nothing.
return v.visitList(n.Ninit) || v.visitList(n.Nbody) || return v.visitList(n.Ninit) || v.visitList(n.Nbody) ||
v.visitList(n.Rlist) v.visitList(n.Rlist)

View file

@ -6,6 +6,7 @@ package gc
import ( import (
"fmt" "fmt"
"go/constant"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -803,7 +804,7 @@ func (p *noder) sum(x syntax.Expr) *Node {
chunks := make([]string, 0, 1) chunks := make([]string, 0, 1)
n := p.expr(x) n := p.expr(x)
if Isconst(n, CTSTR) && n.Sym == nil { if Isconst(n, constant.String) && n.Sym == nil {
nstr = n nstr = n
chunks = append(chunks, nstr.StringVal()) chunks = append(chunks, nstr.StringVal())
} }
@ -812,7 +813,7 @@ func (p *noder) sum(x syntax.Expr) *Node {
add := adds[i] add := adds[i]
r := p.expr(add.Y) r := p.expr(add.Y)
if Isconst(r, CTSTR) && r.Sym == nil { if Isconst(r, constant.String) && r.Sym == nil {
if nstr != nil { if nstr != nil {
// Collapse r into nstr instead of adding to n. // Collapse r into nstr instead of adding to n.
chunks = append(chunks, r.StringVal()) chunks = append(chunks, r.StringVal())

View file

@ -13,6 +13,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/json" "encoding/json"
"fmt" "fmt"
"go/constant"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@ -263,7 +264,7 @@ func dumpGlobalConst(n *Node) {
case TUINTPTR: case TUINTPTR:
// ok // ok
case TIDEAL: case TIDEAL:
if !Isconst(n, CTINT) { if !Isconst(n, constant.Int) {
return return
} }
x := n.Val().U.(*Mpint) x := n.Val().U.(*Mpint)

View file

@ -7,6 +7,7 @@ package gc
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"go/constant"
"html" "html"
"os" "os"
"path/filepath" "path/filepath"
@ -1277,7 +1278,7 @@ func (s *state) stmt(n *Node) {
// We're assigning a slicing operation back to its source. // We're assigning a slicing operation back to its source.
// Don't write back fields we aren't changing. See issue #14855. // Don't write back fields we aren't changing. See issue #14855.
i, j, k := rhs.SliceBounds() i, j, k := rhs.SliceBounds()
if i != nil && (i.Op == OLITERAL && i.Val().Ctype() == CTINT && i.Int64Val() == 0) { if i != nil && (i.Op == OLITERAL && i.Val().Kind() == constant.Int && i.Int64Val() == 0) {
// [0:...] is the same as [:...] // [0:...] is the same as [:...]
i = nil i = nil
} }
@ -1305,7 +1306,7 @@ func (s *state) stmt(n *Node) {
s.assign(n.Left, r, deref, skip) s.assign(n.Left, r, deref, skip)
case OIF: case OIF:
if Isconst(n.Left, CTBOOL) { if Isconst(n.Left, constant.Bool) {
s.stmtList(n.Left.Ninit) s.stmtList(n.Left.Ninit)
if n.Left.BoolVal() { if n.Left.BoolVal() {
s.stmtList(n.Nbody) s.stmtList(n.Nbody)
@ -2093,7 +2094,7 @@ func (s *state) expr(n *Node) *ssa.Value {
} }
default: default:
s.Fatalf("unhandled OLITERAL %v", n.Val().Ctype()) s.Fatalf("unhandled OLITERAL %v", n.Val().Kind())
return nil return nil
} }
case OCONVNOP: case OCONVNOP:
@ -2617,7 +2618,7 @@ func (s *state) expr(n *Node) *ssa.Value {
case OINDEX: case OINDEX:
switch { switch {
case n.Left.Type.IsString(): case n.Left.Type.IsString():
if n.Bounded() && Isconst(n.Left, CTSTR) && Isconst(n.Right, CTINT) { if n.Bounded() && Isconst(n.Left, constant.String) && Isconst(n.Right, constant.Int) {
// Replace "abc"[1] with 'b'. // Replace "abc"[1] with 'b'.
// Delayed until now because "abc"[1] is not an ideal constant. // Delayed until now because "abc"[1] is not an ideal constant.
// See test/fixedbugs/issue11370.go. // See test/fixedbugs/issue11370.go.
@ -2629,7 +2630,7 @@ func (s *state) expr(n *Node) *ssa.Value {
i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
ptrtyp := s.f.Config.Types.BytePtr ptrtyp := s.f.Config.Types.BytePtr
ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a) ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
if Isconst(n.Right, CTINT) { if Isconst(n.Right, constant.Int) {
ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64Val(), ptr) ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64Val(), ptr)
} else { } else {
ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i) ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i)

View file

@ -7,6 +7,7 @@ package gc
import ( import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/src" "cmd/internal/src"
"go/constant"
"sort" "sort"
) )
@ -442,7 +443,7 @@ func (c *exprClause) test(exprname *Node) *Node {
} }
// Optimize "switch true { ...}" and "switch false { ... }". // Optimize "switch true { ...}" and "switch false { ... }".
if Isconst(exprname, CTBOOL) && !c.lo.Type.IsInterface() { if Isconst(exprname, constant.Bool) && !c.lo.Type.IsInterface() {
if exprname.BoolVal() { if exprname.BoolVal() {
return c.lo return c.lo
} else { } else {

View file

@ -7,6 +7,7 @@ package gc
import ( import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"fmt" "fmt"
"go/constant"
"strings" "strings"
) )
@ -359,7 +360,7 @@ func typecheck1(n *Node, top int) (res *Node) {
case OLITERAL: case OLITERAL:
ok |= ctxExpr ok |= ctxExpr
if n.Type == nil && n.Val().Ctype() == CTSTR { if n.Type == nil && n.Val().Kind() == constant.String {
n.Type = types.UntypedString n.Type = types.UntypedString
} }
@ -425,7 +426,7 @@ func typecheck1(n *Node, top int) (res *Node) {
} else { } else {
n.Left = indexlit(typecheck(n.Left, ctxExpr)) n.Left = indexlit(typecheck(n.Left, ctxExpr))
l := n.Left l := n.Left
if consttype(l) != CTINT { if consttype(l) != constant.Int {
switch { switch {
case l.Type == nil: case l.Type == nil:
// Error already reported elsewhere. // Error already reported elsewhere.
@ -802,7 +803,7 @@ func typecheck1(n *Node, top int) (res *Node) {
n.Right = nil n.Right = nil
} }
if (op == ODIV || op == OMOD) && Isconst(r, CTINT) { if (op == ODIV || op == OMOD) && Isconst(r, constant.Int) {
if r.Val().U.(*Mpint).CmpInt64(0) == 0 { if r.Val().U.(*Mpint).CmpInt64(0) == 0 {
yyerror("division by zero") yyerror("division by zero")
n.Type = nil n.Type = nil
@ -1044,15 +1045,15 @@ func typecheck1(n *Node, top int) (res *Node) {
break break
} }
if !n.Bounded() && Isconst(n.Right, CTINT) { if !n.Bounded() && Isconst(n.Right, constant.Int) {
x := n.Right.Int64Val() x := n.Right.Int64Val()
if x < 0 { if x < 0 {
yyerror("invalid %s index %v (index must be non-negative)", why, n.Right) yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
} else if t.IsArray() && x >= t.NumElem() { } else if t.IsArray() && x >= t.NumElem() {
yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem()) yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem())
} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.StringVal())) { } else if Isconst(n.Left, constant.String) && x >= int64(len(n.Left.StringVal())) {
yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.StringVal())) yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.StringVal()))
} else if n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { } else if doesoverflow(n.Right.Val(), types.Types[TINT]) {
yyerror("invalid %s index %v (index too large)", why, n.Right) yyerror("invalid %s index %v (index too large)", why, n.Right)
} }
} }
@ -1147,15 +1148,15 @@ func typecheck1(n *Node, top int) (res *Node) {
l = defaultlit(l, types.Types[TINT]) l = defaultlit(l, types.Types[TINT])
c = defaultlit(c, types.Types[TINT]) c = defaultlit(c, types.Types[TINT])
if Isconst(l, CTINT) && l.Int64Val() < 0 { if Isconst(l, constant.Int) && l.Int64Val() < 0 {
Fatalf("len for OSLICEHEADER must be non-negative") Fatalf("len for OSLICEHEADER must be non-negative")
} }
if Isconst(c, CTINT) && c.Int64Val() < 0 { if Isconst(c, constant.Int) && c.Int64Val() < 0 {
Fatalf("cap for OSLICEHEADER must be non-negative") Fatalf("cap for OSLICEHEADER must be non-negative")
} }
if Isconst(l, CTINT) && Isconst(c, CTINT) && l.Val().U.(*Mpint).Cmp(c.Val().U.(*Mpint)) > 0 { if Isconst(l, constant.Int) && Isconst(c, constant.Int) && compareOp(l.Val(), OGT, c.Val()) {
Fatalf("len larger than cap for OSLICEHEADER") Fatalf("len larger than cap for OSLICEHEADER")
} }
@ -1196,8 +1197,8 @@ func typecheck1(n *Node, top int) (res *Node) {
yyerror("non-integer len argument in OMAKESLICECOPY") yyerror("non-integer len argument in OMAKESLICECOPY")
} }
if Isconst(n.Left, CTINT) { if Isconst(n.Left, constant.Int) {
if n.Left.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { if doesoverflow(n.Left.Val(), types.Types[TINT]) {
Fatalf("len for OMAKESLICECOPY too large") Fatalf("len for OMAKESLICECOPY too large")
} }
if n.Left.Int64Val() < 0 { if n.Left.Int64Val() < 0 {
@ -1773,7 +1774,7 @@ func typecheck1(n *Node, top int) (res *Node) {
n.Type = nil n.Type = nil
return n return n
} }
if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && l.Val().U.(*Mpint).Cmp(r.Val().U.(*Mpint)) > 0 { if Isconst(l, constant.Int) && r != nil && Isconst(r, constant.Int) && compareOp(l.Val(), OGT, r.Val()) {
yyerror("len larger than cap in make(%v)", t) yyerror("len larger than cap in make(%v)", t)
n.Type = nil n.Type = nil
return n return n
@ -1865,7 +1866,7 @@ func typecheck1(n *Node, top int) (res *Node) {
ls := n.List.Slice() ls := n.List.Slice()
for i1, n1 := range ls { for i1, n1 := range ls {
// Special case for print: int constant is int64, not int. // Special case for print: int constant is int64, not int.
if Isconst(n1, CTINT) { if Isconst(n1, constant.Int) {
ls[i1] = defaultlit(ls[i1], types.Types[TINT64]) ls[i1] = defaultlit(ls[i1], types.Types[TINT64])
} else { } else {
ls[i1] = defaultlit(ls[i1], nil) ls[i1] = defaultlit(ls[i1], nil)
@ -2187,10 +2188,10 @@ func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
} else if tp != nil && tp.NumElem() >= 0 && r.Int64Val() > tp.NumElem() { } else if tp != nil && tp.NumElem() >= 0 && r.Int64Val() > tp.NumElem() {
yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem()) yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
return false return false
} else if Isconst(l, CTSTR) && r.Int64Val() > int64(len(l.StringVal())) { } else if Isconst(l, constant.String) && r.Int64Val() > int64(len(l.StringVal())) {
yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.StringVal())) yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.StringVal()))
return false return false
} else if r.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { } else if doesoverflow(r.Val(), types.Types[TINT]) {
yyerror("invalid slice index %v (index too large)", r) yyerror("invalid slice index %v (index too large)", r)
return false return false
} }
@ -2200,7 +2201,7 @@ func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
} }
func checksliceconst(lo *Node, hi *Node) bool { func checksliceconst(lo *Node, hi *Node) bool {
if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && lo.Val().U.(*Mpint).Cmp(hi.Val().U.(*Mpint)) > 0 { if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && compareOp(lo.Val(), OGT, hi.Val()) {
yyerror("invalid slice index: %v > %v", lo, hi) yyerror("invalid slice index: %v > %v", lo, hi)
return false return false
} }
@ -3431,7 +3432,7 @@ func typecheckfunc(n *Node) {
// The result of stringtoruneslit MUST be assigned back to n, e.g. // The result of stringtoruneslit MUST be assigned back to n, e.g.
// n.Left = stringtoruneslit(n.Left) // n.Left = stringtoruneslit(n.Left)
func stringtoruneslit(n *Node) *Node { func stringtoruneslit(n *Node) *Node {
if n.Left.Op != OLITERAL || n.Left.Val().Ctype() != CTSTR { if n.Left.Op != OLITERAL || n.Left.Val().Kind() != constant.String {
Fatalf("stringtoarraylit %v", n) Fatalf("stringtoarraylit %v", n)
} }
@ -3724,7 +3725,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, CTFLT, CTCPLX: case constant.Int, constant.Float, constant.Complex:
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)
@ -3885,11 +3886,11 @@ func deadcodefn(fn *Node) {
} }
switch n.Op { switch n.Op {
case OIF: case OIF:
if !Isconst(n.Left, CTBOOL) || n.Nbody.Len() > 0 || n.Rlist.Len() > 0 { if !Isconst(n.Left, constant.Bool) || n.Nbody.Len() > 0 || n.Rlist.Len() > 0 {
return return
} }
case OFOR: case OFOR:
if !Isconst(n.Left, CTBOOL) || n.Left.BoolVal() { if !Isconst(n.Left, constant.Bool) || n.Left.BoolVal() {
return return
} }
default: default:
@ -3917,7 +3918,7 @@ func deadcodeslice(nn *Nodes) {
} }
if n.Op == OIF { if n.Op == OIF {
n.Left = deadcodeexpr(n.Left) n.Left = deadcodeexpr(n.Left)
if Isconst(n.Left, CTBOOL) { if Isconst(n.Left, constant.Bool) {
var body Nodes var body Nodes
if n.Left.BoolVal() { if n.Left.BoolVal() {
n.Rlist = Nodes{} n.Rlist = Nodes{}
@ -3961,7 +3962,7 @@ func deadcodeexpr(n *Node) *Node {
case OANDAND: case OANDAND:
n.Left = deadcodeexpr(n.Left) n.Left = deadcodeexpr(n.Left)
n.Right = deadcodeexpr(n.Right) n.Right = deadcodeexpr(n.Right)
if Isconst(n.Left, CTBOOL) { if Isconst(n.Left, constant.Bool) {
if n.Left.BoolVal() { if n.Left.BoolVal() {
return n.Right // true && x => x return n.Right // true && x => x
} else { } else {
@ -3971,7 +3972,7 @@ func deadcodeexpr(n *Node) *Node {
case OOROR: case OOROR:
n.Left = deadcodeexpr(n.Left) n.Left = deadcodeexpr(n.Left)
n.Right = deadcodeexpr(n.Right) n.Right = deadcodeexpr(n.Right)
if Isconst(n.Left, CTBOOL) { if Isconst(n.Left, constant.Bool) {
if n.Left.BoolVal() { if n.Left.BoolVal() {
return n.Left // true || x => true return n.Left // true || x => true
} else { } else {

View file

@ -11,6 +11,7 @@ import (
"cmd/internal/sys" "cmd/internal/sys"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"go/constant"
"strings" "strings"
) )
@ -1045,15 +1046,15 @@ opswitch:
} }
if t.IsArray() { if t.IsArray() {
n.SetBounded(bounded(r, t.NumElem())) n.SetBounded(bounded(r, t.NumElem()))
if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, CTINT) { if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
Warn("index bounds check elided") Warn("index bounds check elided")
} }
if smallintconst(n.Right) && !n.Bounded() { if smallintconst(n.Right) && !n.Bounded() {
yyerror("index out of bounds") yyerror("index out of bounds")
} }
} else if Isconst(n.Left, CTSTR) { } else if Isconst(n.Left, constant.String) {
n.SetBounded(bounded(r, int64(len(n.Left.StringVal())))) n.SetBounded(bounded(r, int64(len(n.Left.StringVal()))))
if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, CTINT) { if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
Warn("index bounds check elided") Warn("index bounds check elided")
} }
if smallintconst(n.Right) && !n.Bounded() { if smallintconst(n.Right) && !n.Bounded() {
@ -1061,8 +1062,8 @@ opswitch:
} }
} }
if Isconst(n.Right, CTINT) { if Isconst(n.Right, constant.Int) {
if n.Right.Val().U.(*Mpint).CmpInt64(0) < 0 || n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { if n.Right.Val().U.(*Mpint).CmpInt64(0) < 0 || doesoverflow(n.Right.Val(), types.Types[TINT]) {
yyerror("index out of bounds") yyerror("index out of bounds")
} }
} }
@ -1192,7 +1193,7 @@ opswitch:
// Type checking guarantees that TIDEAL size is positive and fits in an int. // Type checking guarantees that TIDEAL size is positive and fits in an int.
// The case of size overflow when converting TUINT or TUINTPTR to TINT // The case of size overflow when converting TUINT or TUINTPTR to TINT
// will be handled by the negative range checks in makechan during runtime. // will be handled by the negative range checks in makechan during runtime.
if size.Type.IsKind(TIDEAL) || maxintval[size.Type.Etype].Cmp(maxintval[TUINT]) <= 0 { if size.Type.IsKind(TIDEAL) || size.Type.Size() <= types.Types[TUINT].Size() {
fnname = "makechan" fnname = "makechan"
argtype = types.Types[TINT] argtype = types.Types[TINT]
} }
@ -1222,7 +1223,7 @@ opswitch:
// BUCKETSIZE runtime.makemap will allocate the buckets on the heap. // BUCKETSIZE runtime.makemap will allocate the buckets on the heap.
// Maximum key and elem size is 128 bytes, larger objects // Maximum key and elem size is 128 bytes, larger objects
// are stored with an indirection. So max bucket size is 2048+eps. // are stored with an indirection. So max bucket size is 2048+eps.
if !Isconst(hint, CTINT) || if !Isconst(hint, constant.Int) ||
hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 { hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 {
// In case hint is larger than BUCKETSIZE runtime.makemap // In case hint is larger than BUCKETSIZE runtime.makemap
@ -1256,7 +1257,7 @@ opswitch:
} }
} }
if Isconst(hint, CTINT) && hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 { if Isconst(hint, constant.Int) && hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 {
// Handling make(map[any]any) and // Handling make(map[any]any) and
// make(map[any]any, hint) where hint <= BUCKETSIZE // make(map[any]any, hint) where hint <= BUCKETSIZE
// special allows for faster map initialization and // special allows for faster map initialization and
@ -1300,7 +1301,7 @@ opswitch:
// See checkmake call in TMAP case of OMAKE case in OpSwitch in typecheck1 function. // See checkmake call in TMAP case of OMAKE case in OpSwitch in typecheck1 function.
// The case of hint overflow when converting TUINT or TUINTPTR to TINT // The case of hint overflow when converting TUINT or TUINTPTR to TINT
// will be handled by the negative range checks in makemap during runtime. // will be handled by the negative range checks in makemap during runtime.
if hint.Type.IsKind(TIDEAL) || maxintval[hint.Type.Etype].Cmp(maxintval[TUINT]) <= 0 { if hint.Type.IsKind(TIDEAL) || hint.Type.Size() <= types.Types[TUINT].Size() {
fnname = "makemap" fnname = "makemap"
argtype = types.Types[TINT] argtype = types.Types[TINT]
} }
@ -1370,8 +1371,8 @@ opswitch:
// Type checking guarantees that TIDEAL len/cap are positive and fit in an int. // Type checking guarantees that TIDEAL len/cap are positive and fit in an int.
// The case of len or cap overflow when converting TUINT or TUINTPTR to TINT // The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
// will be handled by the negative range checks in makeslice during runtime. // will be handled by the negative range checks in makeslice during runtime.
if (len.Type.IsKind(TIDEAL) || maxintval[len.Type.Etype].Cmp(maxintval[TUINT]) <= 0) && if (len.Type.IsKind(TIDEAL) || len.Type.Size() <= types.Types[TUINT].Size()) &&
(cap.Type.IsKind(TIDEAL) || maxintval[cap.Type.Etype].Cmp(maxintval[TUINT]) <= 0) { (cap.Type.IsKind(TIDEAL) || cap.Type.Size() <= types.Types[TUINT].Size()) {
fnname = "makeslice" fnname = "makeslice"
argtype = types.Types[TINT] argtype = types.Types[TINT]
} }
@ -1486,7 +1487,7 @@ opswitch:
case OSTR2BYTES: case OSTR2BYTES:
s := n.Left s := n.Left
if Isconst(s, CTSTR) { if Isconst(s, constant.String) {
sc := s.StringVal() sc := s.StringVal()
// Allocate a [n]byte of the right size. // Allocate a [n]byte of the right size.
@ -1914,7 +1915,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
t := make([]*Node, 0, len(s)) t := make([]*Node, 0, len(s))
for i := 0; i < len(s); { for i := 0; i < len(s); {
var strs []string var strs []string
for i < len(s) && Isconst(s[i], CTSTR) { for i < len(s) && Isconst(s[i], constant.String) {
strs = append(strs, s[i].StringVal()) strs = append(strs, s[i].StringVal())
i++ i++
} }
@ -1935,11 +1936,11 @@ func walkprint(nn *Node, init *Nodes) *Node {
n = defaultlit(n, types.Runetype) n = defaultlit(n, types.Runetype)
} }
switch n.Val().Ctype() { switch n.Val().Kind() {
case CTINT: case constant.Int:
n = defaultlit(n, types.Types[TINT64]) n = defaultlit(n, types.Types[TINT64])
case CTFLT: case constant.Float:
n = defaultlit(n, types.Types[TFLOAT64]) n = defaultlit(n, types.Types[TFLOAT64])
} }
} }
@ -1994,7 +1995,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
on = syslook("printbool") on = syslook("printbool")
case TSTRING: case TSTRING:
cs := "" cs := ""
if Isconst(n, CTSTR) { if Isconst(n, constant.String) {
cs = n.StringVal() cs = n.StringVal()
} }
switch cs { switch cs {
@ -2850,7 +2851,7 @@ func isAppendOfMake(n *Node) bool {
// The care of overflow of the len argument to make will be handled by an explicit check of int(len) < 0 during runtime. // The care of overflow of the len argument to make will be handled by an explicit check of int(len) < 0 during runtime.
y := second.Left y := second.Left
if !Isconst(y, CTINT) && maxintval[y.Type.Etype].Cmp(maxintval[TUINT]) > 0 { if !Isconst(y, constant.Int) && y.Type.Size() > types.Types[TUINT].Size() {
return false return false
} }
@ -3471,12 +3472,12 @@ func walkcompareString(n *Node, init *Nodes) *Node {
// Rewrite comparisons to short constant strings as length+byte-wise comparisons. // Rewrite comparisons to short constant strings as length+byte-wise comparisons.
var cs, ncs *Node // const string, non-const string var cs, ncs *Node // const string, non-const string
switch { switch {
case Isconst(n.Left, CTSTR) && Isconst(n.Right, CTSTR): case Isconst(n.Left, constant.String) && Isconst(n.Right, constant.String):
// ignore; will be constant evaluated // ignore; will be constant evaluated
case Isconst(n.Left, CTSTR): case Isconst(n.Left, constant.String):
cs = n.Left cs = n.Left
ncs = n.Right ncs = n.Right
case Isconst(n.Right, CTSTR): case Isconst(n.Right, constant.String):
cs = n.Right cs = n.Right
ncs = n.Left ncs = n.Left
} }
@ -3485,7 +3486,7 @@ func walkcompareString(n *Node, init *Nodes) *Node {
// Our comparison below assumes that the non-constant string // Our comparison below assumes that the non-constant string
// is on the left hand side, so rewrite "" cmp x to x cmp "". // is on the left hand side, so rewrite "" cmp x to x cmp "".
// See issue 24817. // See issue 24817.
if Isconst(n.Left, CTSTR) { if Isconst(n.Left, constant.String) {
cmp = brrev(cmp) cmp = brrev(cmp)
} }
@ -3841,17 +3842,17 @@ func candiscard(n *Node) bool {
// Discardable as long as we know it's not division by zero. // Discardable as long as we know it's not division by zero.
case ODIV, OMOD: case ODIV, OMOD:
if Isconst(n.Right, CTINT) && n.Right.Val().U.(*Mpint).CmpInt64(0) != 0 { if Isconst(n.Right, constant.Int) && n.Right.Val().U.(*Mpint).CmpInt64(0) != 0 {
break break
} }
if Isconst(n.Right, CTFLT) && n.Right.Val().U.(*Mpflt).CmpFloat64(0) != 0 { if Isconst(n.Right, constant.Float) && n.Right.Val().U.(*Mpflt).CmpFloat64(0) != 0 {
break break
} }
return false return false
// Discardable as long as we know it won't fail because of a bad size. // Discardable as long as we know it won't fail because of a bad size.
case OMAKECHAN, OMAKEMAP: case OMAKECHAN, OMAKEMAP:
if Isconst(n.Left, CTINT) && n.Left.Val().U.(*Mpint).CmpInt64(0) == 0 { if Isconst(n.Left, constant.Int) && n.Left.Val().U.(*Mpint).CmpInt64(0) == 0 {
break break
} }
return false return false