1
0
mirror of https://github.com/golang/go synced 2024-11-24 01:40:12 -07:00

go/types: check that typed constant shift expressions are representable

Fixes #12945.

Change-Id: I08b44795fcd7ec59371aea8111f7febead54720b
Reviewed-on: https://go-review.googlesource.com/15900
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Matthew Dempsky 2015-10-15 09:50:40 -07:00 committed by Robert Griesemer
parent e920f7d5c5
commit e538e1b627
2 changed files with 18 additions and 2 deletions

View File

@ -618,7 +618,7 @@ func (check *Checker) comparison(x, y *operand, op token.Token) {
x.typ = Typ[UntypedBool] x.typ = Typ[UntypedBool]
} }
func (check *Checker) shift(x, y *operand, op token.Token) { func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) {
untypedx := isUntyped(x.typ) untypedx := isUntyped(x.typ)
// The lhs must be of integer type or be representable // The lhs must be of integer type or be representable
@ -671,6 +671,14 @@ func (check *Checker) shift(x, y *operand, op token.Token) {
x.typ = Typ[UntypedInt] x.typ = Typ[UntypedInt]
} }
x.val = constant.Shift(x.val, op, uint(s)) x.val = constant.Shift(x.val, op, uint(s))
// Typed constants must be representable in
// their type after each constant operation.
if isTyped(x.typ) {
if e != nil {
x.expr = e // for better error message
}
check.representable(x, x.typ.Underlying().(*Basic))
}
return return
} }
@ -753,7 +761,7 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o
} }
if isShift(op) { if isShift(op) {
check.shift(x, &y, op) check.shift(x, &y, e, op)
return return
} }

View File

@ -312,3 +312,11 @@ const (
y64 = float64(f64) y64 = float64(f64)
_ = assert(x64 - y64 == 0) _ = assert(x64 - y64 == 0)
) )
const (
_ = int8(-1) << 7
_ = int8 /* ERROR "overflows" */ (-1) << 8
_ = uint32(1) << 31
_ = uint32 /* ERROR "overflows" */ (1) << 32
)