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