https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95137
--- Comment #10 from Iain Sandoe <iains at gcc dot gnu.org> ---
It seems that the ubsan complaints look all rather similar.
At least for the following case, ubsan seems to cause a change which introduces
a bogus temporary use.
class-00-co-ret.C u=is a very simple coroutine - this is the output of
-fdump-tree-gimple for the main body of the actor function.
without ubsan.
_7 = &frame_ptr->__p;
frame_ptr->__aw_s.is = coro1::promise_type::initial_suspend (_7);
[return slot optimization]
_8 = &frame_ptr->__aw_s.is;
_9 = coro1::suspend_always_prt::await_ready (_8);
retval.0 = ~_9;
if (retval.0 != 0) goto <D.11135>; else goto <D.11136>;
<D.11135>:
frame_ptr->__resume_at = 2;
_10 = &frame_ptr->__aw_s.is;
coro1::suspend_always_prt::await_suspend (_10,
frame_ptr->__self_h);
D.11053 = .CO_YIELD (2, 0, &resume.2, &destroy.2, frame_ptr);
retval.1 = D.11053;
switch (retval.1) <default: <D.11056>, case 0: <D.11054>, case 1:
<D.11055>>
<D.11054>:
.CO_SUSPN (&actor.suspend.ret);
<D.11055>:
goto resume.2;
<D.11056>:
goto destroy.2;
destroy.2:
_11 = &frame_ptr->__aw_s.is;
coro1::suspend_always_prt::~suspend_always_prt (_11);
goto coro.delete.promise;
<D.11136>:
resume.2:
frame_ptr->__i_a_r_c = 1;
_12 = &frame_ptr->__aw_s.is;
coro1::suspend_always_prt::await_resume (_12);
_13 = &frame_ptr->__aw_s.is;
coro1::suspend_always_prt::~suspend_always_prt (_13);
{
puts ("coro1: about to return");
_14 = &frame_ptr->__p;
coro1::promise_type::return_value (_14, 42);
goto final.suspend;
====
with ubsan
_7 = &frame_ptr->__p;
frame_ptr->__aw_s.is = coro1::promise_type::initial_suspend (_7);
[return slot optimization]
D.11410 = &frame_ptr->__aw_s.is;
.UBSAN_NULL (D.11410, 4B, 0);
_8 = coro1::suspend_always_prt::await_ready (D.11410);
retval.0 = ~_8;
if (retval.0 != 0) goto <D.11411>; else goto <D.11412>;
<D.11411>:
frame_ptr->__resume_at = 2;
D.11413 = &frame_ptr->__aw_s.is;
.UBSAN_NULL (D.11413, 4B, 0);
coro1::suspend_always_prt::await_suspend (D.11413,
frame_ptr->__self_h);
D.11322 = .CO_YIELD (2, 0, &resume.2, &destroy.2, frame_ptr);
retval.1 = D.11322;
switch (retval.1) <default: <D.11325>, case 0: <D.11323>, case 1:
<D.11324>>
<D.11323>:
.CO_SUSPN (&actor.suspend.ret);
<D.11324>:
goto resume.2;
<D.11325>:
goto destroy.2;
destroy.2:
D.11415 = &frame_ptr->__aw_s.is;
.UBSAN_NULL (D.11415, 4B, 0);
coro1::suspend_always_prt::~suspend_always_prt (D.11415);
goto coro.delete.promise;
<D.11412>:
resume.2:
frame_ptr->__i_a_r_c = 1;
D.11416 = &frame_ptr->__aw_s.is;
.UBSAN_NULL (D.11416, 4B, 0);
coro1::suspend_always_prt::await_resume (D.11416);
.UBSAN_NULL (D.11415, 4B, 0);
^^^ this is not correct D.11415 is not valid here, (D.11416 would be).
coro1::suspend_always_prt::~suspend_always_prt (D.11415);
{
puts ("coro1: about to return");
D.11417 = &frame_ptr->__p;
.UBSAN_NULL (D.11417, 4B, 4);
coro1::promise_type::return_value (D.11417, 42);
goto final.suspend;
}