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

    <tr>
        <th>Summary</th>
        <td>
            [libc++][test] `nasty_char_traits::move` is incompatible with `constexpr`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++
      </td>
    </tr>

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

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

<pre>
    Found while running libc++'s test suite with MSVC's STL.

`nasty_char_traits::move` is marked `constexpr` but compares unrelated pointers `s1 < s2`. This is forbidden, and `nasty_char_traits::copy` acknowledges this immediately below:

https://github.com/llvm/llvm-project/blob/38f75d606f94e6b552fd74d487b061a1f8f907fa/libcxx/test/support/nasty_string.h#L120-L141

<details><summary>Click to expand compiler error:</summary>

With libc++'s test suite, MSVC's STL, and Clang/LLVM, `std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp` emits this error:

```
D:\GitHub\STL\llvm-project\libcxx\test\std\strings\basic.string\string.modifiers\string_append\initializer_list.pass.cpp(53,17): error: static assertion expression is not an integral constant expression
 static_assert(test());
 ^~~~~~
D:\GitHub\STL\llvm-project\libcxx\test\support\nasty_string.h(122,10): note: comparison between '&s._Mypair._Myval2._Bx._Buf[3]' and '&{CharT(('a')), CharT(('b')), CharT(('c'))}[0]' has unspecified value
 if (s1 < s2) {
 ^
D:\GitHub\STL\out\x64\out\inc\xstring(3311,13): note: in call to 'move(&s._Mypair._Myval2._Bx._Buf[3], &{CharT(('a')), CharT(('b')), CharT(('c'))}[0], 3)'
            _Traits::move(_Old_ptr + _Old_size, _Ptr, _Count);
 ^
D:\GitHub\STL\out\x64\out\inc\xstring(3152,16): note: in call to '&s->append(&{CharT(('a')), CharT(('b')), CharT(('c'))}[0], 3)'
 return append(_Ilist.begin(), _Convert_size<size_type>(_Ilist.size()));
 ^
D:\GitHub\STL\llvm-project\libcxx\test\std\strings\basic.string\string.modifiers\string_append\initializer_list.pass.cpp(27,5): note: in call to '&s->append({&{CharT(('a')), CharT(('b')), CharT(('c'))}[0], &{CharT(('a')), CharT(('b')), CharT(('c'))}[3]})'
  s.append({CharT('a'), CharT('b'), CharT('c')});
 ^
D:\GitHub\STL\llvm-project\libcxx\test\std\strings\basic.string\string.modifiers\string_append\initializer_list.pass.cpp(44,3): note: in call to 'test()'
  test<nasty_string>();
 ^
D:\GitHub\STL\llvm-project\libcxx\test\std\strings\basic.string\string.modifiers\string_append\initializer_list.pass.cpp(53,17): note: in call to 'test()'
  static_assert(test());
 ^
```
</details>

In microsoft/STL's product code, I have a truly marvelous way to avoid this problem - a linear scan to detect whether the first iterator of the destination is within the source range, in which case a backward loop is necessary. See https://github.com/microsoft/STL/blob/0403d19f5461fd15983737c3f01ec34800ea9275/stl/inc/xstring#L85-L93 .
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUV0tv2zgQ_jX0ZRBBIkXLPvgQK_FuARe7QILu0aCkkcWGJgWSsuMe9rcvSD9iZ7dBg6Jd1DAsi48Zft88OCOck2uNOCN8TvjdSAy-M3b24LHvhH5ciq3Y4udRZZr9bGEG3cCukwrBDlpLvQYlq5rQefwWDjw6D26QHmEnfQcfHz6VceLhcZmQ9I6kt8ffcaqF8_tV3Qm78lZI7wi7Jex2Y7ZIxilIBxthn7ABMk5ro53H596GmWrwUJtNLyw6GLRFJTw20BupPVoX1rsMCCvBUTJOE3jspAvyWmMr2TSoCS1B6Cj5K6eoTb8PukT9pM1OYbNGBz7K2WywkcKj2kOFyuzChgtknfd9FEIXhC7W0ndDldRmQ-hCqe3pcdNb8xlrT-iiUqYidMEmbcGbcTpupzmOK85p2xR5k0-KKh1nImsn7TQtWhEEyKp-fiZ0EegmdOGGvjc2_Dugcd5KvU46Qtkyo-nNMsuzK_JZ2aAXUjnC7gkr3bDZCLsn7L5Usn4CbwCf-0BQoFkqtIDWGhupKaPC04ZLsX8Fi3_VIQLnl-5wskGphF4TulguP30MY8F6vglKIgoXGBJO1snh_TyRbEwjW4nWnYdWou9Rh71SSy-Fkl_QrpR0PumFc0nd98GmuJH-aMwzrGvXPH7j612Y5uVv0v8-VISX4ei8vLIhL48W4WW0CC8DgvB7QMDLKwSniQsEp6ETAl5-HQGdcEZomRWETgm7PWMA54WXNQjn0HppdDCiRefCX-lAGw9CQwiStRUKYkwJ7S-WHRAfBa0OggidHNxsEvQFlfPjMsLv_w6f7-Hp6Lm8fO25k4zSgDI9otTGY3geAl86o6FCv0PUQGhB6Nglq4_7XkgbnluhaLKaPyer-dASPmeE3xFaHII-LifFvOyEfYy4JoQWIo5HhLSE67nqjbn6Za64I3yeHlV1IiQn12MdbNzAVqgBj8zJFgidvCQpOgVSXND6FqNmCHQ9j_Pzf6nrMHKKjwljWRaoY6-okxpqoVQIb0KLmGcDgm9hroQfT1kJ8cC0OPJw8Vk9vr4g6GT1h2pWvbdA6Bzii5NfYpZZ_eltfJZm0P61y34ntxmPbjl-k9tA6g1h96d8NPn57Fn0g9VwPsHqQ8wiFa6lPsVypEhv0foDd6wMj5Xf9xhS-3nTgdhT_L-Dz_81SwaWSv5OOxXzn2GqH6kjBmxxdx1KLrmE-CLgReul2Bd9V6MnTQfhv4QP5Dmh5dt58PJyO_MVB9nVpXSIiF8G-XWN8A7o3375_2e5dCgQL8rLi8rqg4aNrK1xpg3FaiwCCwe9Nc1Qh5q-ifn7A3RiiyDA20HtQxewRWUGBzuxDycXWyObQ_3WW1Mp3MANCFBSo7DgaqHDqgY91h52HfoOLfgOoZXWeZAerfDGgmnjaIPOSy38sUwKfYvUccaZwdYIVuh1PJjUofupO6iFC-erRP20E7YBZUwfSyys0Tlh9wk8IMIbrcC_eDi1AWmesiabtjwfZ22T8emEFayoWZtmWLN8kqYoprTgsehVsdStCV2cbyi2nPCb5ZRBMmpmrJmyqRjhLCvSjBc8Z3TUzWjLm5pyVmHWjvO0rbLxtEpzlrf5NMsYH8kZTSnLaMpSxlNGk-l4igwZr4qKpYXISJ7iRkiVBBdPjF2PpHMDzoqc0mykRIXKxY6S0st-gIYO085iXFTD2pE8DW7rXsR46VXsRS-28ZDVDjFz90bHdtE3Sh2rRC8rdexDX7WQo8Gq2bsbtYgxdBsR5j8BAAD__1F-kpk">