aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
diff options
context:
space:
mode:
authorGravatar laurentlb <laurentlb@google.com>2017-07-03 12:16:15 -0400
committerGravatar John Cater <jcater@google.com>2017-07-05 10:57:16 -0400
commit34bbdcf28261378325307baade7267fcfc32860c (patch)
treeef641af9e7bd720c46cc30cc5cc2d30f8c8054a2 /src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
parent97a1db383ccf0e4454a3e4703e0dfb30c20201bf (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.java91
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()));