https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118874
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |iains at gcc dot gnu.org, | |jason at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The ICE is on the <retval>.p = _1; statement (with RTL checking the ICE is because <retval> has DECL_RTL of (parallel:DI [ (expr_list:REG_DEP_TRUE (reg:DI 111 [ <retval> ]) (const_int 0 [0])) ]) and the expansion code just assumes it must be a MEM, doesn't expect the group parallel. This is in the bar function. The function returns struct C, which has non-trivial ctor, just a single pointer member, but doesn't have destructor. Now, if I compile just struct C { void *p; explicit C (void *p) : p(p) {} }; C foo (int i, void *p) { C c (p); return c; } with the same options, then <retval> isn't used at all in the function and one gets D.2304.p = p_2(D); return D.2304; instead. Now, the same compiled with the default options (so 32-bit) has <retval> ={v} {CLOBBER(bob)}; <retval>.p = p_2(D); return <retval>; but in that case flag_pcc_struct_return is true, while for -m64 -mptr64 it is false. Even just #include <coroutine> struct B { bool await_ready () const noexcept; void await_suspend (std::coroutine_handle<> h) const noexcept; void await_resume () const noexcept; }; struct C { struct promise_type { const char *value; std::suspend_never initial_suspend (); std::suspend_always final_suspend () noexcept; void return_value (const char *v); void unhandled_exception (); C get_return_object () { return C{this}; } }; promise_type *p; explicit C (promise_type *p) : p(p) {} const char *get (); }; C bar (bool x) { if (x) co_await B{}; co_return "foobar"; } ICEs the same way, so this doesn't seem to be related to range for. Does this ICE even with older gcc versions which do support coroutines (14, 13, 12, 11, 10)? Some of those need -fcoroutines.