harec

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

commit bbd01c3002170a72e7d82fdabd60dedd0cca9ae4
parent 87c077405904cd63f73c2b66a96b8a10defef19c
Author: Karl Schultheisz <k@kdsch.org>
Date:   Sat, 14 May 2022 22:00:00 -0400

eval: avoid float exception in compile-time exprs

Generate a diagnostic message for compile time expressions with a zero
divisor or modulus, which would cause a floating-point exception during
evaluation.

Signed-off-by: Karl Schultheisz <k@kdsch.org>

Diffstat:
Msrc/eval.c | 26+++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/eval.c b/src/eval.c @@ -181,11 +181,23 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou break; case BIN_DIV: if (type_is_float(lvalue.result)) { - fval = ftrunc(lvalue.result, flval) / ftrunc(rvalue.result, frval); + double r = ftrunc(rvalue.result, frval); + if (r == 0) { + return EVAL_INVALID; + } + fval = ftrunc(lvalue.result, flval) / r; } 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 +217,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;