X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=fold.c;h=8227537bc68f20793b45fcf199c7f35146966341;hp=6d5d37ad403a4130e0fc8a989077c778f93e4831;hb=68c2baa7c1b9ee1ca7804656d6fb5cf65b435a90;hpb=5dc7e62b19dbb8a8c9187ac5f182e671ab08a71d diff --git a/fold.c b/fold.c index 6d5d37a..8227537 100644 --- a/fold.c +++ b/fold.c @@ -48,11 +48,11 @@ typedef union { } sfloat_cast_t; typedef enum { - SFLOAT_INVALID = 1 << 0, - SFLOAT_DIVBYZERO = 1 << 1, - SFLOAT_OVERFLOW = 1 << 2, - SFLOAT_UNDERFLOW = 1 << 3, - SFLOAT_INEXACT = 1 << 4 + SFLOAT_INVALID = 1, + SFLOAT_DIVBYZERO = 4, + SFLOAT_OVERFLOW = 8, + SFLOAT_UNDERFLOW = 16, + SFLOAT_INEXACT = 32 } sfloat_exceptionflags_t; typedef enum { @@ -820,6 +820,9 @@ static bool fold_check_except_float(sfloat_t (*callback)(sfloat_state_t *, sfloa sfloat_cast_t ca; sfloat_cast_t cb; + if (!OPTS_FLAG(ARITHMETIC_EXCEPTIONS) && !OPTS_WARN(WARN_INEXACT_COMPARES)) + return false; + s.roundingmode = SFLOAT_ROUND_NEAREST_EVEN; s.tiny = SFLOAT_TBEFORE; s.exceptionflags = 0; @@ -830,27 +833,26 @@ static bool fold_check_except_float(sfloat_t (*callback)(sfloat_state_t *, sfloa if (s.exceptionflags == 0) return false; + if (!OPTS_FLAG(ARITHMETIC_EXCEPTIONS)) + goto inexact_possible; + if (s.exceptionflags & SFLOAT_DIVBYZERO) compile_error(fold_ctx(fold), "division by zero"); -#if 0 - /* - * To be enabled once softfloat implementations for stuff like sqrt() - * exist - */ if (s.exceptionflags & SFLOAT_INVALID) - compile_error(fold_ctx(fold), "invalid argument"); -#endif - + compile_error(fold_ctx(fold), "undefined (inf)"); if (s.exceptionflags & SFLOAT_OVERFLOW) compile_error(fold_ctx(fold), "arithmetic overflow"); if (s.exceptionflags & SFLOAT_UNDERFLOW) compile_error(fold_ctx(fold), "arithmetic underflow"); - return s.exceptionflags == SFLOAT_INEXACT; +inexact_possible: + return s.exceptionflags & SFLOAT_INEXACT; } static bool fold_check_inexact_float(fold_t *fold, ast_value *a, ast_value *b) { lex_ctx_t ctx = fold_ctx(fold); + if (!OPTS_WARN(WARN_INEXACT_COMPARES)) + return false; if (!a->inexact && !b->inexact) return false; return compile_warning(ctx, WARN_INEXACT_COMPARES, "inexact value in comparison");