commit a347ffcb11f2194ebd42889f586c0d4d8095ab59
parent 29f272f8b1cb52a0b310a82dabf450b6eddaafba
Author: Karl Schultheisz <k@kdsch.org>
Date: Tue, 17 May 2022 09:31:56 -0400
eval: avoid integer div-by-0 in compile-time expr
Generate a diagnostic message for integer-typed compile-time
expressions with a zero divisor or modulus, which would raise SIGFPE
during evaluation.
A previous patch (now reverted) should not have forbade these
operations for floats, which (in the default floating-point
environment) raise no signal.
Signed-off-by: Karl Schultheisz <k@kdsch.org>
Diffstat:
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/eval.c b/src/eval.c
@@ -183,9 +183,17 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou
if (type_is_float(lvalue.result)) {
fval = ftrunc(lvalue.result, flval) / ftrunc(rvalue.result, frval);
} else if (type_is_signed(lvalue.result)) {
- ival = itrunc(lvalue.result, ilval) / itrunc(rvalue.result, irval);
+ uintmax_t r = itrunc(rvalue.result, irval);
+ if (r == 0) {
+ return EVAL_INVALID;
+ }
+ ival = itrunc(lvalue.result, ilval) / r;
} else {
- uval = itrunc(lvalue.result, ulval) / itrunc(rvalue.result, urval);
+ uintmax_t r = itrunc(rvalue.result, urval);
+ if (r == 0) {
+ return EVAL_INVALID;
+ }
+ uval = itrunc(lvalue.result, ulval) / r;
}
break;
case BIN_LSHIFT:
@@ -205,8 +213,16 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou
case BIN_MODULO:
assert(!type_is_float(lvalue.result));
if (type_is_signed(lvalue.result)) {
+ uintmax_t r = itrunc(rvalue.result, irval);
+ if (r == 0) {
+ return EVAL_INVALID;
+ }
ival = itrunc(lvalue.result, ilval) % itrunc(rvalue.result, irval);
} else {
+ uintmax_t r = itrunc(rvalue.result, urval);
+ if (r == 0) {
+ return EVAL_INVALID;
+ }
uval = itrunc(lvalue.result, ulval) % itrunc(rvalue.result, urval);
}
break;