]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: check that typed constant shift expressions are representable
authorMatthew Dempsky <mdempsky@google.com>
Thu, 15 Oct 2015 16:50:40 +0000 (09:50 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 19 Oct 2015 17:34:51 +0000 (17:34 +0000)
Fixes #12945.

Change-Id: I08b44795fcd7ec59371aea8111f7febead54720b
Reviewed-on: https://go-review.googlesource.com/15900
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/expr.go
src/go/types/testdata/const1.src

index ce9ea83b97affed50fa5cf76cca94682a0986419..387a32fc159d21227c7885c782572870bb17b298 100644 (file)
@@ -618,7 +618,7 @@ func (check *Checker) comparison(x, y *operand, op token.Token) {
        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)
 
        // 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.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
                }
 
@@ -753,7 +761,7 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o
        }
 
        if isShift(op) {
-               check.shift(x, &y, op)
+               check.shift(x, &y, e, op)
                return
        }
 
index 88e9fad3c11a5ad0acc7c0d467290d630101d6e4..d82770464fa73a4b84cf6dcc35f2583eed5ba3cf 100644 (file)
@@ -312,3 +312,11 @@ const (
        y64 = float64(f64)
        _ = assert(x64 - y64 == 0)
 )
+
+const (
+       _ = int8(-1) << 7
+       _ = int8 /* ERROR "overflows" */ (-1) << 8
+
+       _ = uint32(1) << 31
+       _ = uint32 /* ERROR "overflows" */ (1) << 32
+)