Fix integer literal bounds checks, again
https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.1
MOE_MIGRATED_REVID=136613096
diff --git a/java/com/google/turbine/parse/ConstExpressionParser.java b/java/com/google/turbine/parse/ConstExpressionParser.java
index 7749b71..fd0b010 100644
--- a/java/com/google/turbine/parse/ConstExpressionParser.java
+++ b/java/com/google/turbine/parse/ConstExpressionParser.java
@@ -20,7 +20,6 @@
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
-import com.google.common.primitives.Ints;
import com.google.turbine.diag.TurbineError;
import com.google.turbine.model.Const;
import com.google.turbine.model.TurbineConstantTypeKind;
@@ -29,6 +28,7 @@
import com.google.turbine.tree.Tree.ClassTy;
import com.google.turbine.tree.Tree.Expression;
import com.google.turbine.tree.TurbineOperatorKind;
+import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
/** A parser for compile-time constant expressions. */
@@ -306,9 +306,16 @@
text = "-" + text;
}
long longValue = parseLong(text, radix);
- value =
- new Const.IntValue(
- radix != 10 && longValue == 0xffffffffL ? -1 : Ints.checkedCast(longValue));
+ if (radix == 10) {
+ if (longValue != (int) longValue) {
+ throw error("integer literal out of range", text);
+ }
+ } else {
+ if (Math.abs(longValue) >> 32 != 0) {
+ throw error("integer literal out of range", text);
+ }
+ }
+ value = new Const.IntValue((int) longValue);
break;
}
case LONG:
@@ -545,6 +552,7 @@
return new Tree.AnnoExpr(position, new Tree.Anno(position, name, args.build()));
}
+ @CheckReturnValue
private TurbineError error(String message, Object... args) {
return TurbineError.format(lexer.source(), lexer.position(), message, args);
}
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index 28718c9..36886f4 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -220,6 +220,7 @@
"concat.test",
"static_type_import.test",
"non_const.test",
+ "bounds.test",
};
List<Object[]> tests =
ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/bounds.test b/javatests/com/google/turbine/lower/testdata/bounds.test
new file mode 100644
index 0000000..6acc634
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/bounds.test
@@ -0,0 +1,27 @@
+=== Test.java ===
+public class Test {
+ public static final int MAX_INT_DEC = 2147483647;
+ public static final int MIN_INT_DEC = -2147483648;
+
+ public static final int MAX_INT_HEX = 0x7fff_ffff;
+ public static final int MIN_INT_HEX = 0x8000_0000;
+
+ public static final int MAX_INT_OCT = 0177_7777_7777;
+ public static final int MIN_INT_OCT = 0200_0000_0000;
+
+ public static final int MAX_INT_BIN = 0b0111_1111_1111_1111_1111_1111_1111_1111;
+ public static final int MIN_INT_BIN = 0b1000_0000_0000_0000_0000_0000_0000_0000;
+
+ public static final long MAX_LONG_DEC = 9223372036854775807L;
+ public static final long MIN_LONG_DEC = -9223372036854775808L;
+
+ public static final long MAX_LONG_HEX = 0x7fff_ffff_ffff_ffffL;
+ public static final long MIN_LONG_HEX = 0x8000_0000_0000_0000L;
+
+ public static final long MAX_LONG_OCT = 07_7777_7777_7777_7777_7777L;
+ public static final long MIN_LONG_OCT = 010_0000_0000_0000_0000_0000L;
+
+ public static final long MAX_LONG_BIN = 0b0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;
+ public static final long MIN_LONG_BIN = 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000L;
+
+}
\ No newline at end of file
diff --git a/javatests/com/google/turbine/parse/ParseErrorTest.java b/javatests/com/google/turbine/parse/ParseErrorTest.java
index 23211ce..fea0d03 100644
--- a/javatests/com/google/turbine/parse/ParseErrorTest.java
+++ b/javatests/com/google/turbine/parse/ParseErrorTest.java
@@ -31,17 +31,28 @@
public class ParseErrorTest {
@Test
- public void expression() {
+ public void intBound() {
ConstExpressionParser parser =
new ConstExpressionParser(
- new StreamLexer(
- new UnicodeEscapePreprocessor(
- new SourceFile(null, String.valueOf(Long.MAX_VALUE)))));
+ new StreamLexer(new UnicodeEscapePreprocessor(new SourceFile("<>", "2147483648"))));
try {
parser.expression();
fail("expected parsing to fail");
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage()).contains("Out of range:");
+ } catch (TurbineError e) {
+ assertThat(e.getMessage()).contains("out of range");
+ }
+ }
+
+ @Test
+ public void hexIntBound() {
+ ConstExpressionParser parser =
+ new ConstExpressionParser(
+ new StreamLexer(new UnicodeEscapePreprocessor(new SourceFile("<>", "0x100000000"))));
+ try {
+ parser.expression();
+ fail("expected parsing to fail");
+ } catch (TurbineError e) {
+ assertThat(e.getMessage()).contains("out of range");
}
}