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

    <tr>
        <th>Summary</th>
        <td>
            Semantics of `std::move` and `std::forward` changed in D123345 and now allow invalid code to compile
        </td>
    </tr>

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

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

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

<pre>
    GCC and clang both treat `std::move` and `std::forward` specially in their frontend now as a result of

https://reviews.llvm.org/D123345

and (for GCC) https://gcc.gnu.org/bugzilla/attachment.cgi?id=51732

This change has now enabled `std::move` and `std::forward` to work on incomplete types when they wouldn't usually and allows invalid code to compile on both gcc and clang.

Consider this trivial example
```cpp
template<class T1, class T2> struct pair { T1 first; T2 second; };
template<class T> struct array {};
struct incomplete; // incomplete type
struct test {
  test(test&& t) : data{std::move(t.data)} {} // This compiles but shouldn't
  array<pair<int, incomplete>> data; // T1 is complete, T2 is incomplete
};
```

If you implement your own `std::move` as can be seen here
```cpp
template<typename T>
constexpr std::remove_reference_t<T>&& move(T&& t) noexcept {
  return static_cast<std::remove_reference_t<T>&&>(t);
}
struct test {
 test(test&& t) : data{move(t.data)} {} 
  array<pair<int, incomplete>> data;
};
```

When compiled this will produce the correct error
```
<source>: In instantiation of 'struct pair<int, incomplete>':
<source>:14:44:   required from here
   14 |     test(test&& other) : data{move(other.data)} {}
      | ^
<source>:3:26: error: 'pair<T1, T2>::second' has incomplete type
    3 | struct pair { T1 first; T2 second; };
      | ^~~~~~~~~
<source>:12:8: note: forward declaration of 'struct incomplete'
   12 | struct incomplete;
      |        ^~~~~~~~~~
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyUVkFz2zgP_TX0BVOPRNqWddBBUepOz19mvmOHImGLuzSpJaG42UN_-w4pNXEaN7vRZCLJhB6A90CAMkZzcogN296x7f1KTjT40JyCHAdDeJaRMKx6r5-aL10H0mlQVroT9J4GoICSgO2KSJqJlon27B-R7YpseP370YeLDDotxRGVkdY-gXFAA5oAx-AdodPg_AVkBAkB42QJ_JEVLSvagWiMCYkfGD8EfDR4iWtrH89rH06MH-5LLsRmO1tn53x_9AG-dB3jNbz-_qTU-uSm5dN-Ov1trJWMHySRVMMZHa3VyTBxMJqJ-21ZCT4jPwwmghqkOyEMMuZ40cneov4oDeTh4sOf4B0Yp_x5tEgI9DRihMuAmZonuPjJasd4RTDFKbOWMKW1_hLBuEdpjQblNSbABGMsJsysz0mpF8nWcwqdd9FoDEApFwrm0UgL-F2mCJLJrpj_1DiyoiU8j1YSMtEpK2OEh5LxDpZnzsRniBQmRTBKE4BVd_BQwtGESEzcwQOHiMo7nV5Ydc_E3U3QKxwZgnxKQM_my8ILTRksS_krdy_WhJEyStFCfmF8P992jO-AUlkw0YKWJFl191o6vqd1XuA1q-6XYH66nItgpjpCPxHE4Vmm7C6nwESXKGGiM44SZ9fxf04JZw8vqTyUsABnG94l9ky8_q5on0l51mmW9esRnvwEJhmmAk5vAfzF3a7LCEo66BEiooMBw_vSJ2qdPGMWihWt8i4Sfh8DPEMHTODfAh4xoFP4jZjosvlM-MLrwzX_zuN3heOLTgFpCg4iSTLqm5KpiLr_6iI_7BPwwlB1f7sc_r0a3iuCjwv8jmz_Tzt9qSU9b8mLsRbG4PWkMDUBUD4EVAQYgg-_Qogu-imo2WMLX1M3iSQdGUnGO_BHYLy62qK_C5dXieQ3iOWGiXaT_kGS56_JBNSpYZ9_Vg0AlBtgVQfpesutpwHDbX7z0luOZ1CADMq2n99GJZhok-DtQopoU5ZLenOHyr1prpulA_Eq9-y3HSO5EtnZx1vZq0B_LNcNGjkT7T7F6Xziu4VlFIBGZWW4IdaVPLxaeObXUb7qh69CWa6riH5c181KN0LXopYrbMpKbHa7QtT1amgKzsWur4-q2my3Qmm90f1e60IorsqyFyvT8IJvSs6Lghc7Ua_3SpS6rnc1r468rpBtCjxLY59n88rEOGFT8mK326-s7NHGn4eN0CSrT_10imxTWBPpZaavyJDF5n94TrWsYubmYxN2ntM6HTOW40G2zmeMND9_Nz5XU7DNLycGQ8PUr5U_M35IIS63T2Pwf6Aixg85z8j4YUn1seH_BAAA__-FxOC4">