[Bug middle-end/98465] [11 Regression] Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::string::insert

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Feb 4 16:58:08 GMT 2021


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.


More information about the Gcc-bugs mailing list