<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/133306>133306</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
std::string assignment generates an unnecessary range check
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
benbms
</td>
</tr>
</table>
<pre>
When a std::string is constructed from a string literal there is unnecessary code being generated for a range check. With short strings, the value is inline in the instructions so there is no source pointer to check, but the range check emits the string to read only data so it can get the address of something. With longer strings, I would expect the compiler to know that a read only data won't overlap with a writable string.
Are the two range checks in char_traits.h needed when memmove allows overlapping ranges?
relevant code from char_traits.h:
```
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
"char_traits::copy: source and destination ranges overlap");
std::__constexpr_memmove(__s1, __s2, __element_count(__n));
return __s1;
}
```
test program on godbolt with compiler x86-64 clang 20.1.0 (assertions):
https://godbolt.org/z/3szThdsa8
```
// -O2 -stdlib=libc++
#include <string>
void string_generates_unnecessary_range_check() {
void f(const std::string&) noexcept;
f("1234567");
}
void string_optimized_away_but_range_check_remains() {
std::string s = "12345";
}
```
output:
```string_generates_unnecessary_range_check():
sub rsp, 24
mov byte ptr [rsp], 14
// range check:
lea rax, [rsp + 1]
lea rcx, [rsp + 8]
lea rdx, [rip + .L.str]
cmp rax, rdx
seta sil
cmp rcx, rdx
setbe cl
or cl, sil
je .LBB0_4
// copy string:
mov dword ptr [rax + 3], 926299444
mov dword ptr [rax], 875770417
mov byte ptr [rsp + 8], 0
mov rdi, rsp
call f(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&)@PLT
test byte ptr [rsp], 1
je .LBB0_3
mov rsi, qword ptr [rsp]
mov rdi, qword ptr [rsp + 16]
and rsi, -2
call operator delete(void*, unsigned long)@PLT
.LBB0_3:
add rsp, 24
ret
.LBB0_4:
ud2
string_optimized_away_but_range_check_remains():
lea rax, [rsp - 23]
lea rcx, [rsp - 18]
lea rdx, [rip + .L.str.1]
cmp rax, rdx
seta al
cmp rcx, rdx
setbe cl
or cl, al
je .LBB1_1
ret
.LBB1_1:
ud2
.L.str:
.asciz "1234567"
.L.str.1:
.asciz "12345"
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJycV19P-zgW_TTuyxVV4qT_HvrQlnYWiQUEaIc3y4kvrWdcO2s7FPj0Kztpm3SKduaHKgXZ5_47Pvc64c7JrUack9GSjG4HvPY7Y-cF6mLvBoURX_Pfd6iBg_OCZAuSLZy3Um9BOiiNdt7WpUcB79bsIypuKunRcgV-hxYDtNYaS3SO2y8ojUAoMOC2qNHyaG8scLBcbxHKHZZ_DuF36Xfgdsb61q0jdBVcwgdXdXQrtZIaQeq4LNt0pNEOnDlH1wacqW2JUBmpPVrwpokSPBa1j-ad4IB76V1cbSvyBixyAUarLxDc8xBAeii5hi02DrgQFp0D8w7O7NHvpN62ZSijt2i7ddzBwdRKAH5WWDb2pdlXUjXZ_anNAfyO-8BKP_DBaEInHswHWsUrOIQAHA5Wel6oY8ZDkixIslhYjL79wXQLDNRBueOWeculd8MdaESBAg7huPe435sPBK6UObhjpCoQEZ04km0a_xYVfnDtm1ONKui5DZpJFmSctL9kAc5zL8vj2bH7u-Xq6Yn96-52zTbPj_9mi-XdaXX1-PDyun57emYvdw-rNVu9vdGkjfBVIaHBO0Bpqi9Cp911YMylgeioUrjcomHLyW9kHhjThM6APTyu31brp1cgk2Vwe0xi8fKyfn5lD48P7PE_6-f7xdPT3cNv7Hnx8Nv6hdApoempOxiTjrUqY1KzSBeh02M24QmELpugqzaVGaGrWMjf_SOUdmhuQkcSssVR6lwLEOi81Dx0RHtwx7MkNIbNlm3YTgGRMPysLGtl0E-fNk9UuEftWWlq7SNCxzo6Pi362urmINpFMrm9kANJFh6dh8qareV7MBq2RhRG-UbYp6b4nI5vxjmUiust0GSYDhMgdMqdQxtbPsYO_nbeV5ETuiF003obGrsldPNN6CZz36874fj0MpWIh5tHCjfOCyULkt0qWZSELsMvIDKpS1ULBJKtmkYj2bop48NI0TYfOw42xzqTrxEDawfPNGiuVRoAROv3IOKo14txS-g4wLXBzxIrf-b4PTqiKc3y0XjSPdWW6n5epvJyL79RMH7gX6yofTcpZnHPZWDyIrnL4e-AZLdwjBuidkP2T9fUvqr9xRz4ZzQ1xuDqIorfuipokOadltmbj_gsvjxC5S2Q0TLgRrcBmubn4-1MwdavQt745Z8B3FjGJk2D_TnICVheAqd_BVpxAskGNLwfOm_7yHJfdWMHo_OmQx8DOqnC6glbXscWGByqzqKxbRTVjLvu3h8Iw_vlMmEdbsIIgaOsF1foFQdjxYlf_hnrylqWZ3RMZ7M8j-fyk0WLnU5Gk0mSp5P_f4ZngukKkit4K2Tkw1VdYrlSxwbpDLe0-afgTpbsWOkqzNLI0F-AvSnb4LL1dWi4LEvuje0As3Vz_zT9S_Lk6f41JBlH3s9y7R9T_GvOKrtWvovl_7dHdOPrR64uwY3ax32bcIO0zm_oFWpNFZrXWBCo0IdrIoyacCfTFdQ6vlmK-OrTrf1YSE9fXIgfW9uiP5nlrVktaDNdfmGu9SNfb_4boNnf6f0bSK-0fkP09fYfpr8wALi6ZvGLY4CrH-SVsii8M99pI-0z-kR7O8p6m0PuSvkN_duogx6mV_G9a6RzRQzEPBOzbMYHOE8neZYmo3ScD3bzrJyNKE1mOM5GyTtN87TMRhwnSMuRmFA6kHOa0FGS0Uk6G9E8H5bvnI9KmuaU0hwFJ3kSBKGGSn3sw4vBQDpX4zzNsiwZDxQvULn4SUSpxgPE3ZDe6HZg58Hopqi3juSJks67sxsvvcL55W3ZfGSFt6XTB48DrnsfRZ1baVBbNb94h5F-VxfD0uwJ3YRo7eOmsuYPLD2hm5ijI3TTFvExp_8LAAD__2WZFHM">