This was fixed on trunk by r15-4473-g3abe751ea86e34, but that isn't
suitable for backporting. Instead, just add another unreachable
condition in std::vector::_M_range_insert so the compiler knows this
memcpy doesn't use a length originating from a negative ptrdiff_t
converted to a very positive size_t.
libstdc++-v3/ChangeLog:
PR libstdc++/117983
* include/bits/vector.tcc (vector::_M_range_insert): Add
unreachable condition to tell the compiler begin() <= end().
* testsuite/23_containers/vector/modifiers/insert/117983.cc: New
test.
(cherry picked from commit 878812b6f6905774ab37cb78903e3e11bf1c508c)
---
Tested x86_64-linux.
This warning is a regression on 12/13/14 so this is needed on all
release branches.
libstdc++-v3/include/bits/vector.tcc | 2 ++
.../vector/modifiers/insert/117983.cc | 17 +++++++++++++++++
2 files changed, 19 insertions(+)
create mode 100644
libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/117983.cc
diff --git a/libstdc++-v3/include/bits/vector.tcc
b/libstdc++-v3/include/bits/vector.tcc
index 0458d560075..b7f472ae09c 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -1002,6 +1002,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// reachable.
pointer __old_start = this->_M_impl._M_start;
pointer __old_finish = this->_M_impl._M_finish;
+ if ((__old_finish - __old_start) < 0)
+ __builtin_unreachable();
const size_type __len =
_M_check_len(__n, "vector::_M_range_insert");
diff --git
a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/117983.cc
b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/117983.cc
new file mode 100644
index 00000000000..e6027a677ee
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/117983.cc
@@ -0,0 +1,17 @@
+// { dg-options "-O3 -Werror=stringop-overflow" }
+// { dg-do compile }
+
+// PR libstdc++/117983
+// -Wstringop-overflow false positive for __builtin_memmove from vector::insert
+
+#include <vector>
+
+typedef std::vector<unsigned char> bytes;
+
+void push(bytes chunk, bytes& data) {
+ if (data.empty()) {
+ data.swap(chunk);
+ } else {
+ data.insert(data.end(), chunk.begin(), chunk.end());
+ }
+}
--
2.49.0