https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98465
--- Comment #24 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Ok, so for GCC 11, can we just help the optimizers a little bit and at the same time get rid of the warning? Like: --- libstdc++-v3/include/bits/basic_string.tcc.jj 2021-01-04 10:26:02.930960956 +0100 +++ libstdc++-v3/include/bits/basic_string.tcc 2021-02-04 17:44:10.592843195 +0100 @@ -477,7 +477,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__s + __len2 <= __p + __len1) this->_S_move(__p, __s, __len2); +#if _GLIBCXX_HAS_BUILTIN(__builtin_object_size) && defined(__OPTIMIZE__) + /* Help the optimizers rule out impossible cases and + get rid of false positive warnings at the same time. + If we know the maximum size of the __s object and + it is shorter than 2 * __len2 - __len1, then + __s >= __p + __len1 case is impossible. */ + else if (!(__builtin_constant_p((2 * __len2 - __len1) + * sizeof(_CharT)) + && __builtin_object_size(__s, 0) + < (2 * __len2 - __len1) * sizeof(_CharT)) + && __s >= __p + __len1) +#else else if (__s >= __p + __len1) +#endif this->_S_copy(__p, __s + __len2 - __len1, __len2); else { I don't get the warning anymore and function size on #c0 testcase shrunk with -O2 -std=gnu++20 -Wall from 614 bytes to 568. This code is handling the non-disjunct case, and when __s >= __p + __len1 and __len1 < __len2, we need to copy from (__s + __len2 - __len1) __len2, i.e. have access up to __s + 2 * __len2 - __len1 - 1. If we know that is certainly out of bounds, most likely it isn't the non-disjunct case at all, but even if it would, this copying wouldn't be a valid option.