<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/120200>120200</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang] [coroutine] Possible over optimization of co_return
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          NewSigma
      </td>
    </tr>
</table>

<pre>
    Hi, clang community

I want to discuss an unusual usage of coroutine and CRTP. The following code gives the expected result using MSVC, but a unpredictable result using GCC and clang. Intert a printf into final_suspend helps clang give the expected result.

A similar discussion is on [GCC Bugzilla](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118074).

https://godbolt.org/z/5rGjKPhW1

clang version: 16.0.0 ~ trunk
Build option: -std=c++20 -O2
```
#include <cstdio>
#include <utility>
#include <coroutine>

template<class T>
struct CRCoro { // Curiously Recurring Coroutine
    struct RValueWrapper {
        T* p;

        operator T&&() const noexcept { return std::move(*p); }
    };

    using promise_type = T;

    T& getDerived() noexcept { return *static_cast<T*>(this); }

    auto get_return_object() noexcept { return RValueWrapper(&getDerived()); }
 std::suspend_never initial_suspend() noexcept { return {}; }
 std::suspend_never final_suspend() noexcept {
 //printf("final_suspend\n");
        return {};
    }
    void return_value(T&& x) noexcept { getDerived() = std::move(x); }
    void unhandled_exception() {}
};

struct A : public CRCoro<A> {
    int a;
};

A func() {
    A aa{};
    aa.a = 5;
    co_return std::move(aa);
}

int main() {
    printf("%d\n", func().a);
 return 0;
}
```
Expected result(MSVC): 5
Possible result of clang: -387938488

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyEVVuPozYU_jXOy9EgYyCBhzwQstmuqrar2dHuY2SMA94aG_mSuTz0t1cGZkIy022EFISPv_N950qtFa3ifIuyHcr2K-pdp832T_74TbQ9XdW6ed7-JhCpgEmqWmC6770S7hnhEuHyCzxS5cBpaIRl3lqgCrzy1lMJ3tKWgz4B00Z7JxQHqhqo7h--RvDQcThpKfWjGGEbDq04cwuu48CfBs4cb8Bw66UDb4PRH9--V4FJ7R1Q8GowvBHM0Vrya8PPVTV6GilH8EU5bsKVwQjlTiCU03ASisqj9XbgqoGOy8HOEgONj1hEk-QSrOiFpOZVstAKhAWtAGW74Hrn2xchJUXZHpG8c26wKCkROSByaBmLWuUjbVpEDvWrJTnYTj8ea99GrBUoOYgGJfs4zvEmRaSYXd9A6abW0s1QL4gcMvP55-9fux_xZD7JOXMTKKKkhHgd4QjDP-CMV38jXO68kA3owc0Gd9YFvwyRHSI7guHuLxKw1nh-cIlIIhSTvuGAkopZ1wiNkk_vTrwTMpTJB0dv5TAf4tLxfpDU8XAoqbXwMB1ZZzxzUN1X2mhAmx1M0qHyRmhv5TPcc-aNCVmv3mBxCQAwX77_TqXnPwwdBm4Cxnwcfg-IlDCgZDfReP2sB26o0yacr8cnR6QAppV1oDR_YnxwIx3DnTcKxrCVKCl7feajdTkgUqBkB2izn5HD29LTVKuD0b2w_OiehxCcfZC-MAoMoOVuz40482Zm8hEHRErrqBPsyKh1KKmCuBBGkrtO2Cs6Mzj1Tgfw4wRx1PVPztwvfFzFcrRb33K7lv0WmLnRjoqfuQGhhBOX9vuVqs1uitv_IF618wd44epUO9MQGE3I9a2sUoiQScCiGm6ZLNI5vZ21aGar4zkECJF8rhx4eifsXTJD0m8L6Old9YxOvOqoaiRvjhNgaNsZZGKHy2WVzR1QQujtwddSsLmXUFKF2li0g1AO6HxzAVHCySu2cDJZl0DpbUAojegoJrt8Y_r4Hy1C6Vug32oycOipUO_cLXOGSHZJVbWgF10QX3OGrxwsptin69GOSD4tlyJEKkO4_KqtFYvFErZYGKfjlEzyTZHkaZ4jXK6abdIUSUFXfBtvkjQlWZKtV92WJk12itO8qDGpT1laF3xdF0VTbLK42ODTSmwJJmlM4g3O0yJeRxuenmiexuucFziJM5Ri3lMhIynPfRjzK2Gt59uYYILxStKaSztubkImcoSEJW624cJd7VuLUiyFdfYC4YST47qfbmT7sLUuEznbw5t0HRorLIdevNBQa9MunzO68kZubzaScJ2vI6Z7RA7B4_x3Nxg9TZbDqMAicphFnLfk3wAAAP__90-UHw">