harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

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:
Msrc/eval.c | 20++++++++++++++++++--
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;