Don't crash when evaluating non-constant expressions
MOE_MIGRATED_REVID=136542923
diff --git a/java/com/google/turbine/binder/ConstEvaluator.java b/java/com/google/turbine/binder/ConstEvaluator.java
index a6368a5..d4c0520 100644
--- a/java/com/google/turbine/binder/ConstEvaluator.java
+++ b/java/com/google/turbine/binder/ConstEvaluator.java
@@ -261,11 +261,18 @@
}
private Const.Value evalConditional(Conditional t) {
- return evalValue(t.cond()).asBoolean().value() ? evalValue(t.iftrue()) : evalValue(t.iffalse());
+ Const.Value condition = evalValue(t.cond());
+ if (condition == null) {
+ return null;
+ }
+ return condition.asBoolean().value() ? evalValue(t.iftrue()) : evalValue(t.iffalse());
}
private Const.Value evalUnary(Unary t) {
Const.Value expr = evalValue(t.expr());
+ if (expr == null) {
+ return null;
+ }
switch (t.op()) {
case NOT:
switch (expr.constantTypeKind()) {
@@ -334,6 +341,9 @@
private Const.Value evalCast(TypeCast t) {
Const.Value expr = evalValue(t.expr());
+ if (expr == null) {
+ return null;
+ }
switch (t.ty().kind()) {
case PRIM_TY:
return coerce(expr, ((Tree.PrimTy) t.ty()).tykind());
@@ -679,6 +689,9 @@
private Const.Value evalBinary(Binary t) {
Const.Value lhs = evalValue(t.lhs());
Const.Value rhs = evalValue(t.rhs());
+ if (lhs == null || rhs == null) {
+ return null;
+ }
switch (t.op()) {
case PLUS:
return add(lhs, rhs);
@@ -836,7 +849,11 @@
private Const.ArrayInitValue evalArrayInit(ArrayInit t) {
ImmutableList.Builder<Const> elements = ImmutableList.builder();
for (Expression e : t.exprs()) {
- elements.add(eval(e));
+ Const arg = eval(e);
+ if (arg == null) {
+ return null;
+ }
+ elements.add(arg);
}
return new Const.ArrayInitValue(elements.build());
}
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index 0d3984a..28718c9 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -219,6 +219,7 @@
"interface_field.test",
"concat.test",
"static_type_import.test",
+ "non_const.test",
};
List<Object[]> tests =
ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/non_const.test b/javatests/com/google/turbine/lower/testdata/non_const.test
new file mode 100644
index 0000000..def461a
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/non_const.test
@@ -0,0 +1,15 @@
+=== Anno.java ===
+public @interface Anno {
+ int[] value() default {};
+}
+
+=== Test.java ===
+class Test {
+ private static int[] xs = {};
+ public static final int A = xs.length;
+ public static final int B = 0 + xs.length;
+ public static final int C = (xs.length > 0) ? 1 : 0;
+ public static final int D = -xs.length;
+ public static final short E = (short) xs.length;
+ public static final int[] F = {xs.length};
+}