-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
libc++ contains assertions of the following form:
llvm-project/libcxx/include/__string/char_traits.h
Lines 239 to 246 in 933ad5c
| static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { | |
| if (!__libcpp_is_constant_evaluated()) | |
| _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES( | |
| __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range"); | |
| std::copy_n(__s2, __n, __s1); | |
| return __s1; | |
| } |
These are enabled with _LIBCPP_ENABLE_SAFE_MODE and are, among other places, used when constructing std::strings from string literals:
llvm-project/libcxx/include/string
Line 940 in 933ad5c
| __init(__s, traits_type::length(__s)); |
llvm-project/libcxx/include/string
Line 2168 in 933ad5c
| traits_type::copy(std::__to_address(__p), __s, __sz); |
Looking at the disassembly of some code in Chromium, this does not seem to get optimized out, even when all we're doing is constructing a std::string from a string literal. The compiler should know that string literals cannot alias with much of anything.
I put together this minimal program in godbolt and it seems, even with -O3, Clang (and GCC) do not optimize these checks out. That suggests Clang (and GCC) just don't know how to optimize this pattern? Separately, I'm not sure if the check is correct. See the comment about the "fixed" versions.
https://godbolt.org/z/oef93T9xb