@@ -730,14 +730,14 @@ func (check *Checker) comparison(x, y *operand, op token.Token) {
730
730
731
731
// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
732
732
func (check * Checker ) shift (x , y * operand , e ast.Expr , op token.Token ) {
733
- untypedx := isUntyped ( x . typ )
733
+ // TODO(gri) This function seems overly complex. Revisit.
734
734
735
735
var xval constant.Value
736
736
if x .mode == constant_ {
737
737
xval = constant .ToInt (x .val )
738
738
}
739
739
740
- if isInteger (x .typ ) || untypedx && xval != nil && xval .Kind () == constant .Int {
740
+ if isInteger (x .typ ) || isUntyped ( x . typ ) && xval != nil && xval .Kind () == constant .Int {
741
741
// The lhs is of integer type or an untyped constant representable
742
742
// as an integer. Nothing to do.
743
743
} else {
@@ -749,16 +749,26 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
749
749
750
750
// spec: "The right operand in a shift expression must have integer type
751
751
// or be an untyped constant representable by a value of type uint."
752
- switch {
753
- case isInteger (y .typ ):
754
- // nothing to do
755
- case isUntyped (y .typ ):
752
+
753
+ // Provide a good error message for negative shift counts.
754
+ if y .mode == constant_ {
755
+ yval := constant .ToInt (y .val ) // consider -1, 1.0, but not -1.1
756
+ if yval .Kind () == constant .Int && constant .Sign (yval ) < 0 {
757
+ check .invalidOp (y , _InvalidShiftCount , "negative shift count %s" , y )
758
+ x .mode = invalid
759
+ return
760
+ }
761
+ }
762
+
763
+ // Caution: Check for isUntyped first because isInteger includes untyped
764
+ // integers (was bug #43697).
765
+ if isUntyped (y .typ ) {
756
766
check .convertUntyped (y , Typ [Uint ])
757
767
if y .mode == invalid {
758
768
x .mode = invalid
759
769
return
760
770
}
761
- default :
771
+ } else if ! isInteger ( y . typ ) {
762
772
check .invalidOp (y , _InvalidShiftCount , "shift count %s must be integer" , y )
763
773
x .mode = invalid
764
774
return
@@ -816,7 +826,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
816
826
}
817
827
818
828
// non-constant shift with constant lhs
819
- if untypedx {
829
+ if isUntyped ( x . typ ) {
820
830
// spec: "If the left operand of a non-constant shift
821
831
// expression is an untyped constant, the type of the
822
832
// constant is what it would be if the shift expression
0 commit comments