aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/expr.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-01-29 15:29:36 -0800
committerRobert Griesemer <gri@golang.org>2021-02-04 22:15:24 +0000
commit370e9f58432c51bf3d95308cdc7109e25cc141f6 (patch)
tree8d690bf0c3f7f9b9c7789fcc6385fd8767c22691 /src/cmd/compile/internal/types2/expr.go
parentca2f15289337f57dcfb938000af249532f79e4d4 (diff)
downloadgo-370e9f58432c51bf3d95308cdc7109e25cc141f6.tar.gz
go-370e9f58432c51bf3d95308cdc7109e25cc141f6.zip
[dev.typeparams] cmd/compile/internal/types2: use 512 bits as max. integer precision
This matches the compiler's existing limitations and thus ensures that types2 reports the same errors for oversize integer constants. Change-Id: I4fb7c83f3af69098d96f7b6c53dbe3eaf6ea9ee4 Reviewed-on: https://go-review.googlesource.com/c/go/+/288633 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/expr.go')
-rw-r--r--src/cmd/compile/internal/types2/expr.go45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index a1a626fb33..679495d3f3 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -96,9 +96,7 @@ func (check *Checker) overflow(x *operand) {
what := "" // operator description, if any
if op, _ := x.expr.(*syntax.Operation); op != nil {
pos = op.Pos()
- if int(op.Op) < len(op2str) {
- what = op2str[op.Op]
- }
+ what = opName(op)
}
if x.val.Kind() == constant.Unknown {
@@ -117,15 +115,37 @@ func (check *Checker) overflow(x *operand) {
}
// Untyped integer values must not grow arbitrarily.
- const limit = 4 * 512 // 512 is the constant precision - we need more because old tests had no limits
- if x.val.Kind() == constant.Int && constant.BitLen(x.val) > limit {
+ const prec = 512 // 512 is the constant precision
+ if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
check.errorf(pos, "constant %s overflow", what)
x.val = constant.MakeUnknown()
}
}
-// This is only used for operations that may cause overflow.
-var op2str = [...]string{
+// opName returns the name of an operation, or the empty string.
+// For now, only operations that might overflow are handled.
+// TODO(gri) Expand this to a general mechanism giving names to
+// nodes?
+func opName(e *syntax.Operation) string {
+ op := int(e.Op)
+ if e.Y == nil {
+ if op < len(op2str1) {
+ return op2str1[op]
+ }
+ } else {
+ if op < len(op2str2) {
+ return op2str2[op]
+ }
+ }
+ return ""
+}
+
+// Entries must be "" or end with a space.
+var op2str1 = [...]string{
+ syntax.Xor: "bitwise complement",
+}
+
+var op2str2 = [...]string{
syntax.Add: "addition",
syntax.Sub: "subtraction",
syntax.Xor: "bitwise XOR",
@@ -800,8 +820,17 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
if x.mode == constant_ {
if y.mode == constant_ {
+ // if either x or y has an unknown value, the result is unknown
+ if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
+ x.val = constant.MakeUnknown()
+ // ensure the correct type - see comment below
+ if !isInteger(x.typ) {
+ x.typ = Typ[UntypedInt]
+ }
+ return
+ }
// rhs must be within reasonable bounds in constant shifts
- const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64
+ const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see issue #44057)
s, ok := constant.Uint64Val(y.val)
if !ok || s > shiftBound {
check.invalidOpf(y, "invalid shift count %s", y)