diff options
| author | Stefan Eßer <se@FreeBSD.org> | 2015-01-27 18:04:41 +0000 |
|---|---|---|
| committer | Stefan Eßer <se@FreeBSD.org> | 2015-01-27 18:04:41 +0000 |
| commit | 8da97f00573902efb70b1732b550edacf673fef5 (patch) | |
| tree | 86ce4c17b6bfb4b31eef245e89c775c6b500e9a0 /bin/expr | |
| parent | b489a49fc0b64eab08d5af8f6f173bf47fe8e1fc (diff) | |
Notes
Diffstat (limited to 'bin/expr')
| -rw-r--r-- | bin/expr/expr.y | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/bin/expr/expr.y b/bin/expr/expr.y index 1856ec84d0f7..0ddf3990d2a8 100644 --- a/bin/expr/expr.y +++ b/bin/expr/expr.y @@ -444,14 +444,26 @@ op_minus(struct val *a, struct val *b) return (r); } +/* + * We depend on undefined behaviour giving a result (in r). + * To test this result, pass it as volatile. This prevents + * optimizing away of the test based on the undefined behaviour. + */ void -assert_times(intmax_t a, intmax_t b, intmax_t r) +assert_times(intmax_t a, intmax_t b, volatile intmax_t r) { /* - * if first operand is 0, no overflow is possible, - * else result of division test must match second operand + * If the first operand is 0, no overflow is possible, + * else the result of the division test must match the + * second operand. + * + * Be careful to avoid overflow in the overflow test, as + * in assert_div(). Overflow in division would kill us + * with a SIGFPE before getting the test wrong. In old + * buggy versions, optimization used to give a null test + * instead of a SIGFPE. */ - if (a != 0 && r / a != b) + if ((a == -1 && b == INTMAX_MIN) || (a != 0 && r / a != b)) errx(ERR_EXIT, "overflow"); } |
