]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/types2: report constant overflow in binary ops
authorRobert Griesemer <gri@golang.org>
Fri, 20 Nov 2020 01:49:05 +0000 (17:49 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 20 Nov 2020 02:39:33 +0000 (02:39 +0000)
This is the go.types changes of https://golang.org/cl/271706
ported to types2.

Also: Fixed a bug in the go/types version (was using the
wrong position in the error message).

Change-Id: I798b80243a66f0be5b943a6951d7a1ff769abca2
Reviewed-on: https://go-review.googlesource.com/c/go/+/271806
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/fixedbugs/issue20583.src [new file with mode: 0644]
src/cmd/compile/internal/types2/stmt.go
src/go/types/expr.go

index 94649ca4cceff3d7416e3c4fa38e96485989d1fb..e166e9926c7a833815706abf35fe87018fd7082c 100644 (file)
@@ -897,7 +897,7 @@ var binaryOpPredicates = opPredicates{
 }
 
 // The binary expression e may be nil. It's passed in for better error messages only.
-func (check *Checker) binary(x *operand, e *syntax.Operation, lhs, rhs syntax.Expr, op syntax.Operator) {
+func (check *Checker) binary(x *operand, e *syntax.Operation, lhs, rhs syntax.Expr, op syntax.Operator, opPos syntax.Pos) {
        var y operand
 
        check.expr(x, lhs)
@@ -977,6 +977,14 @@ func (check *Checker) binary(x *operand, e *syntax.Operation, lhs, rhs syntax.Ex
                        tok = token.QUO_ASSIGN
                }
                x.val = constant.BinaryOp(xval, tok, yval)
+               // report error if valid operands lead to an invalid result
+               if xval.Kind() != constant.Unknown && yval.Kind() != constant.Unknown && x.val.Kind() == constant.Unknown {
+                       // TODO(gri) We should report exactly what went wrong. At the
+                       //           moment we don't have the (go/constant) API for that.
+                       //           See also TODO in go/constant/value.go.
+                       check.errorf(opPos, "constant result is not representable")
+                       // TODO(gri) Should we mark operands with unknown values as invalid?
+               }
                // Typed constants must be representable in
                // their type after each constant operation.
                if isTyped(typ) {
@@ -1791,7 +1799,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
                }
 
                // binary expression
-               check.binary(x, e, e.X, e.Y, e.Op)
+               check.binary(x, e, e.X, e.Y, e.Op, e.Y.Pos()) // TODO(gri) should have OpPos here (like in go/types)
                if x.mode == invalid {
                        goto Error
                }
diff --git a/src/cmd/compile/internal/types2/fixedbugs/issue20583.src b/src/cmd/compile/internal/types2/fixedbugs/issue20583.src
new file mode 100644 (file)
index 0000000..efc1ace
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue20583
+const (
+       _ = 6e886451608 /* ERROR malformed constant */ /2
+       _ = 6e886451608i /* ERROR malformed constant */ /2
+       _ = 0 * 1e+1000000000 // ERROR malformed constant
+       x = 1e100000000
+       _ = x*x*x*x*x*x*x /* ERROR not representable */ // TODO(gri) this error should be at the last *
+)
index 2f1347faf4c320666f740394d0d49a77dc60e139..d88f65b15e438aed61faf765a04cc2359ecb832e 100644 (file)
@@ -396,7 +396,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
                        }
 
                        var x operand
-                       check.binary(&x, nil, lhs[0], rhs[0], s.Op)
+                       check.binary(&x, nil, lhs[0], rhs[0], s.Op, rhs[0].Pos()) // TODO(gri) should have TokPos here (like in go/types)
                        if x.mode == invalid {
                                return
                        }
index 4e19f304772791f261e0f25eca2e0ef1d550f49f..eb2056125a7b71aecf3efb362cd98ec5146a09a1 100644 (file)
@@ -890,7 +890,7 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o
                        // TODO(gri) We should report exactly what went wrong. At the
                        //           moment we don't have the (go/constant) API for that.
                        //           See also TODO in go/constant/value.go.
-                       check.errorf(atPos(e.OpPos), _InvalidConstVal, "constant result is not representable")
+                       check.errorf(atPos(opPos), _InvalidConstVal, "constant result is not representable")
                        // TODO(gri) Should we mark operands with unknown values as invalid?
                }
                // Typed constants must be representable in