]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c/119651: Fix some unexpected error_mark_node ICEs.
authorRoger Sayle <roger@nextmovesoftware.com>
Thu, 26 Feb 2026 08:03:25 +0000 (08:03 +0000)
committerRoger Sayle <roger@nextmovesoftware.com>
Thu, 26 Feb 2026 08:03:25 +0000 (08:03 +0000)
This patch resolves PR c/119651 and PR c/123472 P4 regressions.

2026-02-26  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
PR c/119651
PR c/123472
* fold-const.cc (tree_nonzero_bits): Rename the original as a
static function taking an additional precision parameter.  Make
this implementation robust to error_mark_node.  Preserve the
original API by checking for error_operand_p before invoking the
static helper function.

gcc/testsuite/ChangeLog
PR c/119651
PR c/123472
* gcc.dg/pr119651.c: New test case.
* gcc.dg/pr123472.c: Likewise.

gcc/fold-const.cc
gcc/testsuite/gcc.dg/pr119651.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr123472.c [new file with mode: 0644]

index 41681d38570f1d50c06e46593082dec86c4d6a55..19f25d40d7f74f4e213dcc0a42dce1ecbfb06fd8 100644 (file)
@@ -16708,10 +16708,11 @@ c_getstr (tree str)
   return getbyterep (str, NULL);
 }
 
-/* Given a tree T, compute which bits in T may be nonzero.  */
+/* Helper for tree_nonzero_bits.  Given a tree T, compute which bits in T
+   may be nonzero, with precision PREC, the precision of T's type.  */
 
-wide_int
-tree_nonzero_bits (const_tree t)
+static wide_int
+tree_nonzero_bits (const_tree t, unsigned prec)
 {
   switch (TREE_CODE (t))
     {
@@ -16721,59 +16722,76 @@ tree_nonzero_bits (const_tree t)
       return get_nonzero_bits (t);
     case NON_LVALUE_EXPR:
     case SAVE_EXPR:
-      return tree_nonzero_bits (TREE_OPERAND (t, 0));
+      return tree_nonzero_bits (TREE_OPERAND (t, 0), prec);
     case BIT_AND_EXPR:
-      return wi::bit_and (tree_nonzero_bits (TREE_OPERAND (t, 0)),
-                         tree_nonzero_bits (TREE_OPERAND (t, 1)));
+      return wi::bit_and (tree_nonzero_bits (TREE_OPERAND (t, 0), prec),
+                         tree_nonzero_bits (TREE_OPERAND (t, 1), prec));
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
-      return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 0)),
-                        tree_nonzero_bits (TREE_OPERAND (t, 1)));
+      return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 0), prec),
+                        tree_nonzero_bits (TREE_OPERAND (t, 1), prec));
     case COND_EXPR:
-      return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 1)),
-                        tree_nonzero_bits (TREE_OPERAND (t, 2)));
+      return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 1), prec),
+                        tree_nonzero_bits (TREE_OPERAND (t, 2), prec));
     CASE_CONVERT:
-      return wide_int::from (tree_nonzero_bits (TREE_OPERAND (t, 0)),
-                            TYPE_PRECISION (TREE_TYPE (t)),
-                            TYPE_SIGN (TREE_TYPE (TREE_OPERAND (t, 0))));
+      if (TREE_TYPE (t) != error_mark_node
+         && !error_operand_p (TREE_OPERAND (t, 0)))
+       {
+         tree op0 = TREE_OPERAND (t, 0);
+         tree inner_type = TREE_TYPE (op0);
+         unsigned inner_prec = TYPE_PRECISION (inner_type);
+         return wide_int::from (tree_nonzero_bits (op0, inner_prec),
+                                prec, TYPE_SIGN (inner_type));
+       }
+      break;
     case PLUS_EXPR:
       if (INTEGRAL_TYPE_P (TREE_TYPE (t)))
        {
-         wide_int nzbits1 = tree_nonzero_bits (TREE_OPERAND (t, 0));
-         wide_int nzbits2 = tree_nonzero_bits (TREE_OPERAND (t, 1));
+         wide_int nzbits1 = tree_nonzero_bits (TREE_OPERAND (t, 0), prec);
+         wide_int nzbits2 = tree_nonzero_bits (TREE_OPERAND (t, 1), prec);
          if (wi::bit_and (nzbits1, nzbits2) == 0)
            return wi::bit_or (nzbits1, nzbits2);
        }
       break;
     case LSHIFT_EXPR:
-      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
+      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
+         && TREE_TYPE (t) != error_mark_node)
        {
          tree type = TREE_TYPE (t);
-         wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0));
-         wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1),
-                                      TYPE_PRECISION (type));
+         wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0), prec);
+         wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1), prec);
          return wi::neg_p (arg1)
                 ? wi::rshift (nzbits, -arg1, TYPE_SIGN (type))
                 : wi::lshift (nzbits, arg1);
        }
       break;
     case RSHIFT_EXPR:
-      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
-        {
+      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
+         && TREE_TYPE (t) != error_mark_node)
+       {
          tree type = TREE_TYPE (t);
-         wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0));
-         wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1),
-                                      TYPE_PRECISION (type));
+         wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0), prec);
+         wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1), prec);
          return wi::neg_p (arg1)
                 ? wi::lshift (nzbits, -arg1)
                 : wi::rshift (nzbits, arg1, TYPE_SIGN (type));
-        }
+       }
       break;
     default:
       break;
     }
 
-  return wi::shwi (-1, TYPE_PRECISION (TREE_TYPE (t)));
+  return wi::shwi (-1, prec);
+}
+
+/* Given a tree T, compute which bits in T may be nonzero.  */
+
+wide_int
+tree_nonzero_bits (const_tree t)
+{
+  if (error_operand_p (t))
+    return wi::shwi (-1, 64);
+  return tree_nonzero_bits (t, TYPE_PRECISION (TREE_TYPE (t)));
 }
 
 /* Helper function for address compare simplifications in match.pd.
diff --git a/gcc/testsuite/gcc.dg/pr119651.c b/gcc/testsuite/gcc.dg/pr119651.c
new file mode 100644 (file)
index 0000000..d89c3c2
--- /dev/null
@@ -0,0 +1,10 @@
+/* PR c/119651 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+int main() {
+   int r = 0;
+   while (r % 2 == 0) {
+   }
+   double r = (double) sizeof(int);  /* { dg-error "conflicting type" } */
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr123472.c b/gcc/testsuite/gcc.dg/pr123472.c
new file mode 100644 (file)
index 0000000..2f690c0
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR c/123472 */
+/* { dg-do compile } */
+/* { do-options "-O2" } */
+
+int a , b , c ;
+__attribute__ ( ( __noinline__ ) ) int fn1 ( ) {
+if ( ( b | ( a != ( a & c ) ) ) == 1 )
+__builtin_abort ( ) ;
+return 0 ;
+}
+int c ( void ) {  /* { dg-error "redeclared as different kind" } */
+a = 5 ;
+c = 1 ; /* { dg-error "lvalue required" } */
+b = 6 ;
+return fn1 ( ) ;
+}