https://gcc.gnu.org/g:71225cd5c97aa0474b2fbf5b9196c416f2489257

commit 71225cd5c97aa0474b2fbf5b9196c416f2489257
Author: Mikael Morin <[email protected]>
Date:   Fri Sep 4 13:57:17 2026 +0200

    range-op: Check for undefined before accessing range type [PR126532]
    
    I hesitated on what the operator reverse range function should do when an
    operand is undefined: either return false without setting any range or set
    varying (well, true and false actually) and return true.  I have finally
    chosen varying/true, which matches what is done when the left hand side is
    undefined.
    
    TODO:  OK for mainline?
    
    -- >8 --
    
    In the reverse range evaluation of the logical and operator, add a check
    that the range is non-undefined before accessing its type.  If the range is
    undefined, fall back to the default case and return a true and false range.
    
            PR tree-optimization/126532
    
    gcc/ChangeLog:
    
            * range-op.cc (operator_logical_and::op1_range): Check the range is
            non-undefined before accessing its type.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/pr126532.c: New test.

Diff:
---
 gcc/range-op.cc                 |  3 ++-
 gcc/testsuite/gcc.dg/pr126532.c | 53 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 350548951f45..ca066c05e381 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -3487,7 +3487,8 @@ operator_logical_and::op1_range (irange &r, tree type,
 
     case BRS_FALSE:
       // A FALSE result when op2 is TRUE, must have op1 FALSE.
-      if (!op2.contains_p (wi::zero (TYPE_PRECISION (op2.type ()))))
+      if (!op2.undefined_p ()
+         && !op2.contains_p (wi::zero (TYPE_PRECISION (op2.type ()))))
        {
          r = range_false (type);
          return true;
diff --git a/gcc/testsuite/gcc.dg/pr126532.c b/gcc/testsuite/gcc.dg/pr126532.c
new file mode 100644
index 000000000000..22fbba0ecebf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126532.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -O2 -fno-tree-vrp -fno-tree-dominator-opts" } */
+
+/* PR tree-optimization/126532
+   The following code used to cause an ICE as the logical and reverse operator
+   range calculation was accessing a range's type without checking it was
+   non-undefined.  */
+
+int f_b, f_r;
+
+__attribute__((noipa)) void
+f (int a)
+{
+  _Bool t1 = f_b;
+  if (t1)
+    {
+      _Bool t3 = a && t1;
+      _Bool t39 = t3 ^ t1;
+      if (t3)
+        ;
+      else if (!a)
+        ;
+      else
+        f_r += 7;
+      if (t39)
+        f_r += 3;
+    }
+}
+
+int
+main (void)
+{
+  for (int b = 0; b < 2; b++)
+    for (int a = -1; a < 2; a++)
+      {
+        int e = 0;
+        f_b = b;
+        f_r = 0;
+        f (a);
+        if (b)
+          {
+            int t3 = (a != 0);
+            int t39 = t3 ^ 1;
+            if (!t3 && a)
+              e += 7;
+            if (t39)
+              e += 3;
+          }
+        if (f_r != e)
+          __builtin_abort ();
+      }
+  return 0;
+}

Reply via email to