<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">