diff --git a/go/types/expr.go b/go/types/expr.go index 1fb0a360168701..e5ae0ba228aec8 100644 --- a/go/types/expr.go +++ b/go/types/expr.go @@ -620,7 +620,7 @@ func (check *Checker) shift(x, y *operand, op token.Token) { // The lhs must be of integer type or be representable // as an integer; otherwise the shift has no chance. - if !isInteger(x.typ) && (!untypedx || !representableConst(x.val, nil, UntypedInt, nil)) { + if !x.isInteger() { check.invalidOp(x.pos(), "shifted operand %s must be integer", x) x.mode = invalid return @@ -646,6 +646,12 @@ func (check *Checker) shift(x, y *operand, op token.Token) { if x.mode == constant { if y.mode == constant { + // rhs must be an integer value + if !y.isInteger() { + check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y) + x.mode = invalid + return + } // rhs must be within reasonable bounds const stupidShift = 1023 - 1 + 52 // so we can express smallestFloat64 s, ok := exact.Uint64Val(y.val) diff --git a/go/types/testdata/shifts.src b/go/types/testdata/shifts.src index 7f8ed06fbfabc0..2df2ccde0b7659 100644 --- a/go/types/testdata/shifts.src +++ b/go/types/testdata/shifts.src @@ -319,3 +319,15 @@ func issue5895() { var x = 'a' << 1 // type of x must be rune var _ rune = x } + +func issue11325() { + var _ = 0 >> 1.1 /* ERROR "must be unsigned integer" */ // example from issue 11325 + _ = 0 >> 1.1 /* ERROR "must be unsigned integer" */ + _ = 0 << 1.1 /* ERROR "must be unsigned integer" */ + _ = 0 >> 1. + _ = 1 >> 1.1 /* ERROR "must be unsigned integer" */ + _ = 1 >> 1. + _ = 1. >> 1 + _ = 1. >> 1. + _ = 1.1 /* ERROR "must be integer" */ >> 1 +}