Skip to content

Commit a7e9b4b

Browse files
committed
[dev.regabi] go/types: untyped shift counts must fit into uint
This is a port of CL 283872 to go/types. It differs from that CL only in added error codes. For #43697 Change-Id: I62277834cef1c0359bcf2c6ee4388731babbc855 Reviewed-on: https://go-review.googlesource.com/c/go/+/291316 Trust: Robert Findley <[email protected]> Trust: Robert Griesemer <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 060fa49 commit a7e9b4b

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

src/go/types/expr.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -730,14 +730,14 @@ func (check *Checker) comparison(x, y *operand, op token.Token) {
730730

731731
// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
732732
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.
734734

735735
var xval constant.Value
736736
if x.mode == constant_ {
737737
xval = constant.ToInt(x.val)
738738
}
739739

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 {
741741
// The lhs is of integer type or an untyped constant representable
742742
// as an integer. Nothing to do.
743743
} else {
@@ -749,16 +749,26 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
749749

750750
// spec: "The right operand in a shift expression must have integer type
751751
// 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) {
756766
check.convertUntyped(y, Typ[Uint])
757767
if y.mode == invalid {
758768
x.mode = invalid
759769
return
760770
}
761-
default:
771+
} else if !isInteger(y.typ) {
762772
check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y)
763773
x.mode = invalid
764774
return
@@ -816,7 +826,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
816826
}
817827

818828
// non-constant shift with constant lhs
819-
if untypedx {
829+
if isUntyped(x.typ) {
820830
// spec: "If the left operand of a non-constant shift
821831
// expression is an untyped constant, the type of the
822832
// constant is what it would be if the shift expression

src/go/types/testdata/shifts.src

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func shifts0() {
2020
// This depends on the exact spec wording which is not
2121
// done yet.
2222
// TODO(gri) revisit and adjust when spec change is done
23-
_ = 1<<- /* ERROR "truncated to uint" */ 1.0
23+
_ = 1<<- /* ERROR "negative shift count" */ 1.0
2424
_ = 1<<1075 /* ERROR "invalid shift" */
2525
_ = 2.0<<1
2626
_ = 1<<1.0
@@ -60,11 +60,13 @@ func shifts1() {
6060
_ uint = 1 << u
6161
_ float32 = 1 /* ERROR "must be integer" */ << u
6262

63-
// for issue 14822
63+
// issue #14822
64+
_ = 1<<( /* ERROR "overflows uint" */ 1<<64)
6465
_ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1)
65-
_ = 1<<( /* ERROR "invalid shift count" */ 1<<64)
66-
_ = u<<(1<<63) // valid
67-
_ = u<<(1<<64) // valid
66+
67+
// issue #43697
68+
_ = u<<( /* ERROR "overflows uint" */ 1<<64)
69+
_ = u<<(1<<64-1)
6870
)
6971
}
7072

0 commit comments

Comments
 (0)