https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108691
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
The reason is that gimple_call_flags returns a different answer from the
indirect function call vs. the direct function call after propagating of
the &setjmp constant. First of all 'returns_twice' is an attribute that
cannot be set on a function type:
int __attribute__((returns_twice)) (*foo) (void);
> gcc-12 -S t.c -Wall
t.c:1:1: warning: 'returns_twice' attribute ignored [-Wattributes]
1 | int __attribute__((returns_twice)) (*foo) (void);
| ^~~
so one cannot have an indirect call annotated. But even then we for
example treat indirect missing 'noreturn' conservatively, not requiring
it to end a BB and only enforce that in the fixup-CFG pass.
Now, for return_twice we could similarly check gimple_call_ctrl_altering.
That still leaves us with missing abnormal edges - David, was this reduced
from an actual program?
When fixing up DCE to not set cfun->calls_setjmp it will eventually be
set late in emit_call_1 via
if (ecf_flags & ECF_RETURNS_TWICE)
{
add_reg_note (call_insn, REG_SETJMP, const0_rtx);
cfun->calls_setjmp = 1;
}
a "fix" here would be to _check_ for cfun->calls_setjmp instead of setting it
(or assert it is set). The control-altering flag has no representation
on GENERIC, and we're still expanding calls via intermediate GENERIC ...