diff options
author | 2017-07-03 12:16:15 -0400 | |
---|---|---|
committer | 2017-07-05 10:57:16 -0400 | |
commit | 34bbdcf28261378325307baade7267fcfc32860c (patch) | |
tree | ef641af9e7bd720c46cc30cc5cc2d30f8c8054a2 /src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java | |
parent | 97a1db383ccf0e4454a3e4703e0dfb30c20201bf (diff) |
New flag `--incompatible_checked_arithmetic` to use checked arithmetics.
RELNOTES:
Evaluation will soon use checked arithmetics and throw an error instead of
overflow/underflow.
PiperOrigin-RevId: 160834366
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java index fdb7f54bb7..06e46dbbdb 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java @@ -144,53 +144,57 @@ public final class BinaryOperatorExpression extends Expression { Object rval = rhs.eval(env); - switch (operator) { - case PLUS: - return plus(lval, rval, env, location, isAugmented); + try { + switch (operator) { + case PLUS: + return plus(lval, rval, env, location, isAugmented); - case PIPE: - return pipe(lval, rval, location); + case PIPE: + return pipe(lval, rval, location); - case MINUS: - return minus(lval, rval, location); + case MINUS: + return minus(lval, rval, env, location); - case MULT: - return mult(lval, rval, env, location); + case MULT: + return mult(lval, rval, env, location); - case DIVIDE: - case FLOOR_DIVIDE: - return divide(lval, rval, location); + case DIVIDE: + case FLOOR_DIVIDE: + return divide(lval, rval, location); - case PERCENT: - return percent(lval, rval, location); + case PERCENT: + return percent(lval, rval, location); - case EQUALS_EQUALS: - return lval.equals(rval); + case EQUALS_EQUALS: + return lval.equals(rval); - case NOT_EQUALS: - return !lval.equals(rval); + case NOT_EQUALS: + return !lval.equals(rval); - case LESS: - return compare(lval, rval, location) < 0; + case LESS: + return compare(lval, rval, location) < 0; - case LESS_EQUALS: - return compare(lval, rval, location) <= 0; + case LESS_EQUALS: + return compare(lval, rval, location) <= 0; - case GREATER: - return compare(lval, rval, location) > 0; + case GREATER: + return compare(lval, rval, location) > 0; - case GREATER_EQUALS: - return compare(lval, rval, location) >= 0; + case GREATER_EQUALS: + return compare(lval, rval, location) >= 0; - case IN: - return in(lval, rval, location, env); + case IN: + return in(lval, rval, location, env); - case NOT_IN: - return !in(lval, rval, location, env); + case NOT_IN: + return !in(lval, rval, location, env); - default: - throw new AssertionError("Unsupported binary operator: " + operator); - } // endswitch + default: + throw new AssertionError("Unsupported binary operator: " + operator); + } // endswitch + } catch (ArithmeticException e) { + throw new EvalException(location, e.getMessage()); + } } @Override @@ -215,7 +219,11 @@ public final class BinaryOperatorExpression extends Expression { throws EvalException { // int + int if (lval instanceof Integer && rval instanceof Integer) { - return ((Integer) lval).intValue() + ((Integer) rval).intValue(); + if (env.getSemantics().incompatibleCheckedArithmetic) { + return Math.addExact((Integer) lval, (Integer) rval); + } else { + return ((Integer) lval).intValue() + ((Integer) rval).intValue(); + } } // string + string @@ -281,9 +289,14 @@ public final class BinaryOperatorExpression extends Expression { } /** Implements Operator.MINUS. */ - private static Object minus(Object lval, Object rval, Location location) throws EvalException { + private static Object minus(Object lval, Object rval, Environment env, Location location) + throws EvalException { if (lval instanceof Integer && rval instanceof Integer) { - return ((Integer) lval).intValue() - ((Integer) rval).intValue(); + if (env.getSemantics().incompatibleCheckedArithmetic) { + return Math.subtractExact((Integer) lval, (Integer) rval); + } else { + return ((Integer) lval).intValue() - ((Integer) rval).intValue(); + } } throw typeException(lval, rval, Operator.MINUS, location); } @@ -304,7 +317,11 @@ public final class BinaryOperatorExpression extends Expression { if (number != null) { if (otherFactor instanceof Integer) { - return number.intValue() * ((Integer) otherFactor).intValue(); + if (env.getSemantics().incompatibleCheckedArithmetic) { + return Math.multiplyExact(number, (Integer) otherFactor); + } else { + return number.intValue() * ((Integer) otherFactor).intValue(); + } } else if (otherFactor instanceof String) { // Similar to Python, a factor < 1 leads to an empty string. return Strings.repeat((String) otherFactor, Math.max(0, number.intValue())); |