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

Reply via email to