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;
            }

Reply via email to