bazel syntax: reject x<<y if y > 31
Because Java's shift operators only use the low 5 bits of y,
we cannot check for overflow simply by unshifting and comparing.
Also, detect overflow of integer division (MININT // -1).
BUG=159942010,159946493
PiperOrigin-RevId: 318537836
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
index d977fa1..d493f27 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
@@ -340,9 +340,9 @@
if (yi < 0) {
throw Starlark.errorf("negative shift count: %d", yi);
}
- int z = xi << yi;
- if (z >> yi != xi) {
- throw Starlark.errorf("integer overflow");
+ int z = xi << yi; // only uses low 5 bits of yi
+ if ((z >> yi) != xi || yi >= 32) {
+ throw Starlark.errorf("integer overflow in left shift");
}
return z;
}
@@ -419,6 +419,9 @@
if ((xi < 0) != (yi < 0) && rem != 0) {
quo--;
}
+ if (xi == Integer.MIN_VALUE && yi == -1) { // HD 2-13
+ throw Starlark.errorf("integer overflow in division");
+ }
return quo;
}
break;
diff --git a/src/test/starlark/testdata/int.sky b/src/test/starlark/testdata/int.sky
index ca3cc67..68d4877 100644
--- a/src/test/starlark/testdata/int.sky
+++ b/src/test/starlark/testdata/int.sky
@@ -131,8 +131,12 @@
---
~False ### unsupported unary operation: ~bool
---
-1 << 31 ### integer overflow
+1 << 31 ### integer overflow in left shift
+---
+1 << 32 ### integer overflow in left shift
---
1 << -4 ### negative shift count: -4
---
2 >> -1 ### negative shift count: -1
+---
+((-1) << 31) // -1 ### integer overflow in division