This patch resolves PR c/119651 and PR c/123716 P4 regressions.
Tested on x86_64-pc-linux-gnu with make bootstrap and make -k check
with no new regressions.  Ok for mainline?


2026-02-17  Roger Sayle  <[email protected]>

gcc/ChangeLog
        PR c/119651
        PR c/123716
        * fold-const.cc (tree_nonzero_bits) <case CONVERT>: Check both
        the inner and outer types are not error_mark_node.
        * tree.cc (tree_nop_conversion_p): Move sanity checks on
        inner_type to here...
        (tree_nop_conversion): .. from here.

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

Roger
--

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 41681d38570..8929c758011 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -16733,6 +16733,9 @@ tree_nonzero_bits (const_tree t)
       return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 1)),
                         tree_nonzero_bits (TREE_OPERAND (t, 2)));
     CASE_CONVERT:
+      if (TREE_TYPE (t) == error_mark_node
+         || TREE_TYPE (TREE_OPERAND (t, 0)) == error_mark_node)
+       break;
       return wide_int::from (tree_nonzero_bits (TREE_OPERAND (t, 0)),
                             TYPE_PRECISION (TREE_TYPE (t)),
                             TYPE_SIGN (TREE_TYPE (TREE_OPERAND (t, 0))));
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 02f98f87003..d0e745e8d28 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -12333,6 +12333,9 @@ block_ultimate_origin (const_tree block)
 bool
 tree_nop_conversion_p (const_tree outer_type, const_tree inner_type)
 {
+  if (!inner_type || inner_type == error_mark_node)
+    return false;
+
   /* Do not strip casts into or out of differing address spaces.  */
   if (POINTER_TYPE_P (outer_type)
       && TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) != ADDR_SPACE_GENERIC)
@@ -12382,8 +12385,6 @@ tree_nop_conversion (const_tree exp)
 
   outer_type = TREE_TYPE (exp);
   inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-  if (!inner_type || inner_type == error_mark_node)
-    return false;
 
   return tree_nop_conversion_p (outer_type, inner_type);
 }
diff --git a/gcc/testsuite/gcc.dg/pr119651.c b/gcc/testsuite/gcc.dg/pr119651.c
new file mode 100644
index 00000000000..d89c3c2b8cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119651.c
@@ -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/pr123716.c b/gcc/testsuite/gcc.dg/pr123716.c
new file mode 100644
index 00000000000..0ac34361e89
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr123716.c
@@ -0,0 +1,9 @@
+/* PR c/123716 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+int f(unsigned s)
+{
+  int i;
+  for (i = 0; i < s; ++i);
+  unsigned i[1];  /* { dg-error "conflicting type" } */
+}

Reply via email to