https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67280

--- Comment #2 from cbaylis at gcc dot gnu.org ---

Minimum optimisations to reproduce this are -O1 -fipa-icf-functions -fipa-sra.
These options also allow the bug to be reproduced on trunk (with -O2 the bug is
latent, I haven't investigated why).

The analysis here also uses -fno-inline, because the wrapper function is more
clearly visible. The problem occurs with and without inlining.

The failure is caused because the function:
   std::_Function_handler<void (),
main::{lambda()#1}>::_M_invoke(std::_Any_data const&)
is compiled to:

_ZNSt17_Function_handlerIFvvEZ4mainEUlvE_E9_M_invokeERKSt9_Any_data:
        .fnstart
.LFB2010:
        @ Volatile: function does not return.
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        push    {r3, lr}
        bl     
_ZNSt17_Function_handlerIFvvEZ4mainEUlvE0_E9_M_invokeERKSt9_Any_data
        .cantunwind
        .fnend

This includes .cantunwind which is an ARM-specific directive which causes the
exception unwinder to stop at this function which causes execution to
terminate.

Going further back, the ARM backend emits this directive because the function
is marked "nothrow" in the ipa-pure-const phase. This is visible in the dump:
foo.cc.062i.pure-const:Function found to be nothrow: static void
std::_Function_handler<void(_ArgTypes ...), _Functor>::_M_invoke(const
std::_Any_data&, _ArgTypes&& ...) [with _Functor = main()::<lambda()>;
_ArgTypes = {}]

This is clearly wrong, because this function calls the lambda, which contains a
throw. This happens on all targets, but does not seem to cause problems on
non-ARM targets because they use the standard/generic unwinder mechanism.

The _ZNSt17_Function_handlerIFvvEZ4mainEUlvE_E9_M_invokeERKSt9_Any_data is a
wrapper, created by cgraph_node::create_wrapper(). When this function updates
the callgraph and creates the edge to the target function, it unconditionally
sets ->can_throw_external to false, which causes the ipa-pure-const phase to
mark the wrapper function as nothrow.

I will send a patch to the mailing list shortly.

Reply via email to