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" } */
+}