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

    <tr>
        <th>Summary</th>
        <td>
            [coroutines/c++] Return object is being prematurely converted.
        </td>
    </tr>

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

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

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

<pre>
    using llvm/clang main built on 2022-07-14.

There appears to be a regression in how coroutine return objects are implicitly converted prior to returning them.

First as background, the `get_return_object` customization point is allowed to return an object that can be implicitly converted to the real return type.  This part is still working fine.

The regression concerns when this implicit conversion happens.

Clang traditionally waited to perform this implicit conversion until after the `return_value` customization point was called.  This allowed doing some tricks that are useful in implementing e.g. a `std::optional` coroutine.  So if you were to print out the order of calls, it would looks like this traditionally:

1. call `get_return_object`
2. call `return_value`
3. do implicit conversion of return object to the type that is actually needed.

This may have changed at some point in the last few months, but the version of clang that I built today does it in a different order:

1. call `get_return object`
2. do implicit conversion of return object to the type that is actually needed.
3. call `return_value`

I'm not sure if the standard guarantees that it will happen in a certain order... but I know that traditionally it used to be done according to the first ordering (which gcc also does), but now that changed, and it is breaking my implementation of the `std::optional` coroutine.

It seems sensible to wait as long as possible to perform the implicit conversion, since it affords flexibility to the user in that it permits the object that `get_return_object` returns to remain alive and accessible to `return_value` (or other customization point methods) until the very end when it is implicitly converted just before ending the coroutine.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJytVstu4zgQ_Br5QkSQ5TiPgw_zQIBcd-Y-oMiWxAklCiQVj_frt5qUEnvWwexhAcGGRLKrurq7pMbp02EOZuyEta9DUT8pK3EzSDOKZjY2CjeKuqrrm-r-ZntbFtXXovqUf7_35EnIaSLpg4hONLgTnjpPIRicQ4zeHYVy3s3RjIS1OPtRuOYnqRiExHEzTNYoE-0J-8ZX8pG0mLxxniPmA0wv9jRcoD8ZH6KQQTRSvXRAGHVRf-F9orirOoo_8uEfGQ3PhJpDdIP5W0ZmNzkzRmFAw1p3BOobnpArR4STUSjcNx9QxSGG9CTtejqeJiqF-N4j9iR9wgjRWCuOzr9wMi3E-F3Kc-EQXpEfgzj2hHgcaAVfoNO2nrUfw0WkL6l-0UttOEvkdhJHaRaqE_nW-eHjkPMIokK2kfwq5SLjq7QzfaTiEXVQwCK9Jr6Kqh0nHNxAIGXUS8iScunnQO1suUuYCQ0EbOylsivRR4AKURe7T7jclHNJ8Gs3AembE6YVJzeLI7ciJ-iZDjYk9s5r5OHaxC1weyDbo5utFtY5cLHmhbIYF4ox6pmm2zIF-Kiv8qb6fdNviuX1XQktrmoOfheDsfYU91FWi_VUcU7FHIk0ZL7sHmwY5AkN8UpC9egAKI9zSfalz8cU00oMTUtHMbgx9kmSZhHrjE42gQT9vNhAdBoA2lFgDRFNCm3aFrKz3qzzfxFN_Fu0_1-U3R8qkX-fi_p-EKODSjP7UJvChyhHLb0W3Sy9HCPR0rDcODzCeeayAJjRyEaZ0i_LMkn5LF5GmF46dDmGCIGW14tTagdDlArtrJO_5fTa5GopID8t6odjb1QvOqUwUsGlChT141q4N6il6vwcGaQawRphS8lwhtP7jOW5de0633-YsgvNIBbRADuD7ZjGppFjd2Eftg5A-J9ceFt79xu6VmVmi5ePIuYrW2zVQbSWfpnGWBNPqyqQzecOzpVA2MHEkGf8zKg_Mv78IGSHT-82aQ1GhZVCCeid8BW_Qw3wMnLA8le9b6DYO81FWdxzGaaTIIRPDp6rcfX98RMR0Q5InXj_8qo703-jDzv9uHuUm4ijdCj2n98WA7-wi_ozX_uv4q-LgeH6E8ebOGes0DlwuZm9PfQxToGrXz_h6kzs56ZUjj8Elu8B_ruZvEtS1k8mhDnB7u_2u3rTH0jXD7R9qO7k3W2lasyhfKC9alW7q7Z3u_3GyoZsYNqguDEH_pio7re39XZb1dvycXt_X-1Uu2_3u7ZVdXFbcYVsycCl893GHxKHZu4CFq0JMbwvSpSuw_Sv8eWMYviDnqTCd0G_SXwPiew_H24bpg">