mirror of
https://github.com/golang/go
synced 2024-11-17 09:24:43 -07:00
[dev.typeparams] cmd/compile/internal/types2: report constant overflow in binary ops
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>
This commit is contained in:
parent
b1ae0a0646
commit
8fbdacf64c
@ -897,7 +897,7 @@ var binaryOpPredicates = opPredicates{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The binary expression e may be nil. It's passed in for better error messages only.
|
// 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
|
var y operand
|
||||||
|
|
||||||
check.expr(x, lhs)
|
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
|
tok = token.QUO_ASSIGN
|
||||||
}
|
}
|
||||||
x.val = constant.BinaryOp(xval, tok, yval)
|
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
|
// Typed constants must be representable in
|
||||||
// their type after each constant operation.
|
// their type after each constant operation.
|
||||||
if isTyped(typ) {
|
if isTyped(typ) {
|
||||||
@ -1791,7 +1799,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// binary expression
|
// 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 {
|
if x.mode == invalid {
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
12
src/cmd/compile/internal/types2/fixedbugs/issue20583.src
Normal file
12
src/cmd/compile/internal/types2/fixedbugs/issue20583.src
Normal file
@ -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 *
|
||||||
|
)
|
@ -396,7 +396,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var x operand
|
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 {
|
if x.mode == invalid {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -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
|
// TODO(gri) We should report exactly what went wrong. At the
|
||||||
// moment we don't have the (go/constant) API for that.
|
// moment we don't have the (go/constant) API for that.
|
||||||
// See also TODO in go/constant/value.go.
|
// 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?
|
// TODO(gri) Should we mark operands with unknown values as invalid?
|
||||||
}
|
}
|
||||||
// Typed constants must be representable in
|
// Typed constants must be representable in
|
||||||
|
Loading…
Reference in New Issue
Block a user