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");
     }
   }