[PATCH v4] libstdc++: Use allocate_at_least in vector, string (P0401) [PR118030]

Nathan Myers ncm@cantrip.org
Wed May 20 16:09:57 GMT 2026


On 5/19/26 7:19 PM, Nathan Myers wrote:
> On 5/19/26 2:43 PM, Rainer Orth wrote:
>>> On 5/19/26 2:06 PM, Rainer Orth wrote:
>>> ...
>>>> allows the build to continue, but it still fails later:
>>>> prev-x86_64-pc-linux-gnu/libstdc++-v3/include/bits/ 
>>>> char_traits.h:432:56:
>>>> error: 'void* __builtin_memcpy(void*, const void*, long unsigned int)'
>>>> accessing 18446744073709551609 or more bytes at offsets 0 and 0 
>>>> overlaps
>>>> 9223372036854775795 bytes at offset -9223372036854775802
>>>> [-Werror=restrict]
>>>>     432 |         return 
>>>> static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
>>>
>>> What were the previous messages? Other similar complaints have
>>> something to do with rounding up numbers that could roll over
>>> to 0x800..000 and then be passed to a library function.
>>
>> the full message was
>>
>> In file included from /var/gcc/regression/master/6.17.13-gcc-gas-gld/ 
>> build/prev-x86_64-pc-linux-gnu/libstdc++-v3/include/string:45,
>>                   from /vol/gcc/src/hg/master/local/gcc/rust/rust- 
>> system.h:34,
>>                   from /vol/gcc/src/hg/master/local/gcc/rust/lex/rust- 
>> token.cc:19:
>> In static member function 'static constexpr 
>> std::char_traits<char>::char_type* 
>> std::char_traits<char>::copy(char_type*, const char_type*, std::size_t)',
>>      inlined from 'static constexpr void 
>> std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, 
>> const _CharT*, size_type) [with _CharT = char; _Traits = 
>> std::char_traits<char>; _Alloc = std::allocator<char>]' at /var/gcc/ 
>> regression/master/6.17.13-gcc-gas-gld/build/prev-x86_64-pc-linux-gnu/ 
>> libstdc++-v3/include/bits/basic_string.h:487:21,
>>      inlined from 'static constexpr void 
>> std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, 
>> const _CharT*, size_type) [with _CharT = char; _Traits = 
>> std::char_traits<char>; _Alloc = std::allocator<char>]' at /var/gcc/ 
>> regression/master/6.17.13-gcc-gas-gld/build/prev-x86_64-pc-linux-gnu/ 
>> libstdc++-v3/include/bits/basic_string.h:482:7,
>>      inlined from 'constexpr void std::__cxx11::basic_string<_CharT, 
>> _Traits, _Alloc>::_M_mutate(size_type, size_type, const _CharT*, 
>> size_type) [with _CharT = char; _Traits = std::char_traits<char>; 
>> _Alloc = std::allocator<char>]' at /var/gcc/regression/master/6.17.13- 
>> gcc-gas-gld/build/prev-x86_64-pc-linux-gnu/libstdc++-v3/include/bits/ 
>> basic_string.tcc:403:15,
>>      inlined from 'constexpr std::__cxx11::basic_string<_CharT, 
>> _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, 
>> _Alloc>::_M_append(const _CharT*, size_type) [with _CharT = char; 
>> _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' at / 
>> var/gcc/regression/master/6.17.13-gcc-gas-gld/build/prev-x86_64-pc- 
>> linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:496:17,
>>      inlined from 'constexpr std::__cxx11::basic_string<_CharT, 
>> _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, 
>> _Alloc>::append(const _CharT*, size_type) [with _CharT = char; _Traits 
>> = std::char_traits<char>; _Alloc = std::allocator<char>]' at /var/gcc/ 
>> regression/master/6.17.13-gcc-gas-gld/build/prev-x86_64-pc-linux-gnu/ 
>> libstdc++-v3/include/bits/basic_string.h:1624:18,
>>      inlined from 'constexpr _Str std::__str_concat(const typename 
>> _Str::value_type*, typename _Str::size_type, const typename 
>> _Str::value_type*, typename _Str::size_type, const typename 
>> _Str::allocator_type&) [with _Str = __cxx11::basic_string<char>]' at / 
>> var/gcc/regression/master/6.17.13-gcc-gas-gld/build/prev-x86_64-pc- 
>> linux-gnu/libstdc++-v3/include/bits/basic_string.h:3908:19,
>>      inlined from 'constexpr std::__cxx11::basic_string<_CharT, 
>> _Traits, _Alloc> std::operator+(const __cxx11::basic_string<_CharT, 
>> _Traits, _Alloc>&, const _CharT*) [with _CharT = char; _Traits = 
>> char_traits<char>; _Alloc = allocator<char>]' at /var/gcc/regression/ 
>> master/6.17.13-gcc-gas-gld/build/prev-x86_64-pc-linux-gnu/libstdc++- 
>> v3/include/bits/basic_string.h:3984:31,
>>      inlined from 'std::string Rust::Token::as_string() const' at / 
>> vol/gcc/src/hg/master/local/gcc/rust/lex/rust-token.cc:251:45:
>> /var/gcc/regression/master/6.17.13-gcc-gas-gld/build/prev-x86_64-pc- 
>> linux-gnu/libstdc++-v3/include/bits/char_traits.h:432:56: error: 
>> 'void* __builtin_memcpy(void*, const void*, long unsigned int)' 
>> accessing 1844674407370955118446744073709551609609 or more bytes at 
>> offsets 0 and 0 overlaps 9223372036854775795 bytes at offset 
>> -9223372036854775802 [-Werror=restrict]
>>    432 |         return static_cast<char_type*>(__builtin_memcpy(__s1, 
>> __s2, __n));
>>
>>     Rainer

[Looking back at the original report, the 40-digit number must
be a cut and paste error. So...]

> /vol/gcc/src/hg/master/local/gcc/rust/lex/rust-token.cc
> 
>     ... get_str () + get_type_hint_str ();
> 

... reaches vector<>::_M_mutate

 > defined at bits/basic_string.tcc:392. The compiler> thinks _M_mutate 
at 403,

   this->_S_copy(__r.__ptr + __pos, __s, __len2);

(with __r.__ptr + __pos pointing immediately past
bytes from get_str()'s result as copied to freshly
allocated memory, and __s and __len2 the contents of
get_type_hint_str()'s result)

> might try to ask memcpy to copy more than is allowed,

to wit, 18446744073709551609, or -7ull.

> The other numbers resolve to -0x7FFF'FFFF'FFF3'
> and 0x7FFF'FFFF'FFFa. I don't know what "offsets 0 and 0"
> might refer to.
Is it saying it thinks the memcpy might be copying
overlapping ranges?

> ... Anyway the patch didn't
> change any of this. The new function _M_create_plus does
> the same job as the old _M_create in the same way, but might
> yield a little bit of extra storage that anyway would not be
> touched yet.
> 
> Earlier versions of this patch evoked a somewhat similar
> complaint about allocate_at_least potentially asking
> __builtin_malloc for more than 0x7fff'ffff'ffff'ffff bytes,
> resolved by subtracting 1 if rounding-up ever actually got
> there.
> 
> The caller of _M_mutate has already verified the value
> passed to its argument __len2 is within bounds. Lower-level
> code multiplies the value by sizeof(_CharT), but it has
> been capped such that the product is not too large.


More information about the Libstdc++ mailing list