https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98465
--- Comment #28 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Actually tested version.

The above testcase with [2, INF] range doesn't make really much sense,
but adjusted testcase where n has [0, 2] range doesn't warn anymore like the
one with constant 2.

diff --git a/libstdc++-v3/include/bits/c++config
b/libstdc++-v3/include/bits/c++config
index b57ff339990..69336a32bc6 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -731,6 +731,10 @@ namespace std
 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
 #endif

+#if _GLIBCXX_HAS_BUILTIN(__builtin_object_size)
+# define _GLIBCXX_HAVE_BUILTIN_OBJECT_SIZE 1
+#endif
+
 #undef _GLIBCXX_HAS_BUILTIN

 #if _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED && __cplusplus >= 201402L
diff --git a/libstdc++-v3/include/bits/basic_string.tcc
b/libstdc++-v3/include/bits/basic_string.tcc
index 5beda8b829b..bc6e0b98186 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -477,7 +477,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                {
                  if (__s + __len2 <= __p + __len1)
                    this->_S_move(__p, __s, __len2);
+#if defined(_GLIBCXX_HAVE_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(__builtin_object_size(__s, 0)
+                                                 < ((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
                    {

Reply via email to