Some things. Fix testsuite as well. One test will fail (inexact).
authorDale Weiler <weilercdale@gmail.com>
Sat, 24 May 2014 15:42:10 +0000 (11:42 -0400)
committerDale Weiler <weilercdale@gmail.com>
Sat, 24 May 2014 15:42:10 +0000 (11:42 -0400)
fold.c
test.c
tests/arithexcept.qc
tests/inexact.qc

diff --git a/fold.c b/fold.c
index 98bbdb745ec27a48fe7e44a45f9c0f2070e0bc89..aca45c0a6cd765b44b4fd46b8a630cd77665038c 100644 (file)
--- 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 c726b02f1ebe0999779525f7e2be087477bb93d2..29f4b1100fb1ea0df4b0bbea4f2eaef206207460 100644 (file)
--- 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]),
index 10476e67fc88bbb2fa37cba2d68a9d6487f73ca3..6441f780e8ba6198f20dbf1526e38234d952a4f4 100644 (file)
@@ -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;
index 873d7ccaca37e9a056b64d2887e26c9a5c73545e..11dc2c62521d0ce9e87ffb8f898f214f647a9edd 100644 (file)
@@ -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
     }