PR analyzer/93290 reports an ICE on calls to isnan().
The root cause is that an UNORDERED_EXPR is passed
to region_model::eval_condition_without_cm, and there's
a stray gcc_unreachable () in the case where we're comparing
an svalue against itself.

I attempted a more involved patch that properly handled NaN in general
but it seems I've baked the assumption of reflexivity too deeply into
the constraint_manager code.

For now, this patch avoids the ICE and documents the limitation.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

Pushed to master as 07c86323a199ca15177d99ad6c488b8f5fb5c729.

gcc/analyzer/ChangeLog:
        PR analyzer/93290
        * region-model.cc (region_model::eval_condition_without_cm): Avoid
        gcc_unreachable for unexpected operations for the case where
        we're comparing an svalue against itself.

gcc/ChangeLog
        * doc/analyzer.texi (Limitations): Add note about NaN.

gcc/testsuite/ChangeLog:
        PR analyzer/93290
        * gcc.dg/analyzer/pr93290.c: New test.
---
 gcc/analyzer/region-model.cc            | 10 ++++++----
 gcc/doc/analyzer.texi                   |  3 +++
 gcc/testsuite/gcc.dg/analyzer/pr93290.c |  9 +++++++++
 3 files changed, 18 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr93290.c

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index f67572e2d45..1e0be312e03 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -5189,13 +5189,11 @@ region_model::eval_condition_without_cm (svalue_id 
lhs_sid,
     {
       if (lhs == rhs)
        {
-         /* If we have the same svalue, then we have equality.
+         /* If we have the same svalue, then we have equality
+            (apart from NaN-handling).
             TODO: should this definitely be the case for poisoned values?  */
          switch (op)
            {
-           default:
-             gcc_unreachable ();
-
            case EQ_EXPR:
            case GE_EXPR:
            case LE_EXPR:
@@ -5205,6 +5203,10 @@ region_model::eval_condition_without_cm (svalue_id 
lhs_sid,
            case GT_EXPR:
            case LT_EXPR:
              return tristate::TS_FALSE;
+
+           default:
+             /* For other ops, use the logic below.  */
+             break;
            }
        }
 
diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi
index b4e9b01da2e..81acdd8998b 100644
--- a/gcc/doc/analyzer.texi
+++ b/gcc/doc/analyzer.texi
@@ -388,6 +388,9 @@ The implementation of call summaries is currently very 
simplistic.
 @item
 Lack of function pointer analysis
 @item
+The constraint-handling code assumes reflexivity in some places
+(that values are equal to themselves), which is not the case for NaN.
+@item
 The region model code creates lots of little mutable objects at each
 @code{region_model} (and thus per @code{exploded_node}) rather than
 sharing immutable objects and having the mutable state in the
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93290.c 
b/gcc/testsuite/gcc.dg/analyzer/pr93290.c
new file mode 100644
index 00000000000..fa35629d955
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93290.c
@@ -0,0 +1,9 @@
+#include <math.h>
+
+int test_1 (void)
+{
+  float foo = 42.;
+  if (isnan (foo))
+    return 1;
+  return 0;
+}
-- 
2.21.0

Reply via email to