Issue 53170
Summary ODR violation in std::string::reserve due to change that makes reserve never reduce capacity
Labels libc++, c++20, regression, miscompilation
Assignees ldionne, mkurdej
Reporter zygoloid
    `std::string::reserve` is part of the precompiled portion of libc++, due to the explicit instantiation of `std::string` in the library. Since 841132efda2157c5f9e07cf31469470a6481ffd9, the function contains this:

```
#if _LIBCPP_STD_VER > 17
    // Reserve never shrinks as of C++20.
    if (__requested_capacity <= capacity()) return;
#endif
```

That results in an ODR violation, even without any mixing of `-std` versions in user code. The version of `std::string::reserve` in the library will be built in C++20 mode (because that's required when building libc++ these days). But a client using `-std=c++17` will either get the C++17 behavior or the C++20 behavior depending on whether the function happens to be inlined (or worse, the optimizer might assume the C++17 behavior and then link against the C++20 version, resulting in unbounded UB).

I think the options are either:
* Use `_LIBCPP_INLINE_VISIBILITY` for this function and increase code size everywhere; the symbol in the libc++ prebuilt library would still exist but would never be used.
* Give this symbol consistent behavior, by always using the C++20 semantics (which are valid semantics in C++17 and before).
* Use some fancy mechanism to switch between different symbols for the C++17 and C++20 semantics.

I previously reported this in https://reviews.llvm.org/D91778#inline-902723; now that libc++ is built in C++20 mode, this is causing actual breakage for us.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to