Issue 74221
Summary [libc++][test] `nasty_char_traits::move` is incompatible with `constexpr`
Labels libc++
Assignees
Reporter StephanTLavavej
    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 .
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to