Hi Richard,

> -----Original Message-----
> From: Richard Biener <[email protected]>
> Sent: 18 February 2026 09:48
> To: Roger Sayle <[email protected]>
> Cc: GCC Patches <[email protected]>
> Subject: Re: [PATCH middle-end] Fix some unexpected error_mark_node ICEs.
> 
> On Tue, Feb 17, 2026 at 10:49 PM Roger Sayle <[email protected]>
> wrote:
> >
> >
> > 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?
> 
> The tree_nop_conversion_p change looks OK.  I wonder where we build the
> CONVERT_EXPR with error operands though, ideally we'd not do this but build
> error_mark_node for itself.

You've asked this question before (can we avoid building error_operand_p 
nodes?).
Here https://gcc.gnu.org/pipermail/gcc-patches/2024-April/650244.html
The problem is tree sharing (similar to RTL sharing in the RTL optimizers).
VAR_DECLs are conceptually placed in a symbol table, and these trees are 
re-used in multiple expressions in a function/compilation unit.  The 
redeclaration
of a variable with conflicting type, causes us to set/update it's type to 
error_mark_node, poisoning not only future uses, but all prior uses of
that variable.  This means that problematic expressions are not error_operand_p
at the time that they are built, but "magically" become error_operands_p at a
later point.

This is a bit like changing the register number in an RTL pseudo register, where
all references to that pseudo change [during register allocation].

I completely agree it's ugly.

One approach might be to consider redeclaration of variables a fatal error,
and refuse to attempt to continue compilation any further.  The alternative
is the current whack-a-mole where we attempt to make the middle-end's
tree optimizers robust to VAR_DECL's with TREE_TYPE error_mark_node.
Automatic fuzz testing finds these ICEs faster than we can review their fixes.

>      CASE_CONVERT:
> +      if (TREE_TYPE (t) == error_mark_node
> 
> this sub-check I'd check
> 
>     if (!error_operand_p (t))
> 
> around the switch.
> 
> +         || TREE_TYPE (TREE_OPERAND (t, 0)) == error_mark_node)
> +       break;

Of course if we'd know that we had an error_operand_p at build
time, we'd have returned error_mark_node instead of constructing
a CASE_CONVERT.

> > 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
> > --


Reply via email to