From: Dale Weiler Date: Sat, 24 May 2014 15:42:10 +0000 (-0400) Subject: Some things. Fix testsuite as well. One test will fail (inexact). X-Git-Tag: xonotic-v0.8.1~9^2~32^2~12 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=05e20bcddaa5cb67b4d2a91323a5dfc17e99a416 Some things. Fix testsuite as well. One test will fail (inexact). --- diff --git a/fold.c b/fold.c index 98bbdb7..aca45c0 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 { @@ -692,6 +692,7 @@ ast_expression *fold_constgen_float(fold_t *fold, qcfloat_t value, bool inexact) out->hasvalue = true; out->inexact = inexact; out->constval.vfloat = value; + (void)inexact; vec_push(fold->imm_float, out); @@ -820,7 +821,7 @@ 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)) + if (!OPTS_FLAG(ARITHMETIC_EXCEPTIONS) && !OPTS_WARN(WARN_INEXACT_COMPARES)) return false; s.roundingmode = SFLOAT_ROUND_NEAREST_EVEN; @@ -833,27 +834,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"); @@ -923,7 +923,11 @@ static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_ if (isfloat(a)) { if (fold_can_2(a, b)) { bool inexact = fold_check_except_float(&sfloat_div, fold, a, b); - return fold_constgen_float(fold, fold_immvalue_float(a) / fold_immvalue_float(b), inexact); + ast_expression *e; + con_out("inexact: %d (%x:%x)\n", inexact, a, b); + e = fold_constgen_float(fold, fold_immvalue_float(a) / fold_immvalue_float(b), inexact); + con_out("%x\n", e); + return e; } else if (fold_can_1(b)) { return (ast_expression*)ast_binary_new( fold_ctx(fold), @@ -1079,6 +1083,7 @@ static GMQCC_INLINE ast_expression *fold_op_cmp(fold_t *fold, ast_value *a, ast_ if (isfloat(a) && isfloat(b)) { float la = fold_immvalue_float(a); float lb = fold_immvalue_float(b); + con_out("CMP: %x:%x\n", a, b); fold_check_inexact_float(fold, a, b); return (ast_expression*)fold->imm_float[!(ne ? la == lb : la != lb)]; } if (isvector(a) && isvector(b)) { diff --git a/test.c b/test.c index c726b02..29f4b11 100644 --- a/test.c +++ b/test.c @@ -1100,6 +1100,7 @@ static size_t task_schedualize(size_t *pad) { size_t i = 0; size_t j = 0; size_t failed = 0; + int status = 0; util_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks)); @@ -1167,7 +1168,9 @@ static size_t task_schedualize(size_t *pad) { continue; } - if (task_pclose(task_tasks[i].runhandles) != EXIT_SUCCESS && strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) { + status = task_pclose(task_tasks[i].runhandles); + if ((!strcmp(task_tasks[i].tmpl->proceduretype, "-fail") && status == EXIT_SUCCESS) + || ( strcmp(task_tasks[i].tmpl->proceduretype, "-fail") && status == EXIT_FAILURE)) { con_out("failure: `%s` %*s %*s\n", task_tasks[i].tmpl->description, (pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]), diff --git a/tests/arithexcept.qc b/tests/arithexcept.qc index 10476e6..6441f78 100644 --- a/tests/arithexcept.qc +++ b/tests/arithexcept.qc @@ -1,4 +1,4 @@ -const float huge = 340282346638528859811704183484516925440; // FLT_MAX +const float huge = 340282346638528859811704183484516925440.000000; // FLT_MAX #ifdef DIVBYZERO const float a = 1.0 / 0.0; diff --git a/tests/inexact.qc b/tests/inexact.qc index 873d7cc..11dc2c6 100644 --- a/tests/inexact.qc +++ b/tests/inexact.qc @@ -1,7 +1,7 @@ -void main() { - const float a = 1.0 / 3.0; - const float b = 0.3333333333333; +const float a = 1.0 / 3.0; +const float b = 0.33333333333; +void main() { if (a == b) { // Should trigger warning }