} 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 {
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;
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");