aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-12-17 17:38:43 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2025-01-08 12:45:37 +0000
commit5f44b1776e748a7528020557036740905a11b1df (patch)
tree2ccf8809cde8b9cf5ed4b0a50bf596d17344d6fa
parent4a4e5394b3001b1b3fb35c274d184ffba30156e8 (diff)
downloadgcc-5f44b1776e748a7528020557036740905a11b1df.zip
gcc-5f44b1776e748a7528020557036740905a11b1df.tar.gz
gcc-5f44b1776e748a7528020557036740905a11b1df.tar.bz2
libstdc++: Fix std::deque::emplace calling wrong _M_insert_aux [PR90389]
We have several overloads of std::deque::_M_insert_aux, one of which is variadic and called by std::deque::emplace. With a suitable set of arguments to emplace, it's possible for one of the non-variadic _M_insert_aux overloads to be selected by overload resolution, making emplace ill-formed. Rename the variadic _M_insert_aux to _M_emplace_aux so that calls to emplace never select an _M_insert_aux overload. Also add an inline _M_insert_aux for the const lvalue overload that is called from insert(const_iterator, const value_type&). libstdc++-v3/ChangeLog: PR libstdc++/90389 * include/bits/deque.tcc (_M_insert_aux): Rename variadic overload to _M_emplace_aux. * include/bits/stl_deque.h (_M_insert_aux): Define inline. (_M_emplace_aux): Declare. * testsuite/23_containers/deque/modifiers/emplace/90389.cc: New test.
-rw-r--r--libstdc++-v3/include/bits/deque.tcc6
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h6
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/90389.cc43
3 files changed, 51 insertions, 4 deletions
diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc
index 42dfa6a..fcbecca 100644
--- a/libstdc++-v3/include/bits/deque.tcc
+++ b/libstdc++-v3/include/bits/deque.tcc
@@ -200,8 +200,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return __tmp;
}
else
- return _M_insert_aux(__position._M_const_cast(),
- std::forward<_Args>(__args)...);
+ return _M_emplace_aux(__position._M_const_cast(),
+ std::forward<_Args>(__args)...);
}
#endif
@@ -646,7 +646,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename... _Args>
typename deque<_Tp, _Alloc>::iterator
deque<_Tp, _Alloc>::
- _M_insert_aux(iterator __pos, _Args&&... __args)
+ _M_emplace_aux(iterator __pos, _Args&&... __args)
{
value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
#else
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 225fac3..6936714 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -2059,9 +2059,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator
_M_insert_aux(iterator __pos, const value_type& __x);
#else
+ iterator
+ _M_insert_aux(iterator __pos, const value_type& __x)
+ { return _M_emplace_aux(__pos, __x); }
+
template<typename... _Args>
iterator
- _M_insert_aux(iterator __pos, _Args&&... __args);
+ _M_emplace_aux(iterator __pos, _Args&&... __args);
#endif
// called by insert(p,n,x) via fill_insert
diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/90389.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/90389.cc
new file mode 100644
index 0000000..b493249
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/90389.cc
@@ -0,0 +1,43 @@
+// { dg-do run { target c++11 } }
+
+// Bug 90389 - std::deque::emplace tries to call wrong overload internally
+
+#include <deque>
+#include <testsuite_hooks.h>
+
+struct X
+{
+ X() = default;
+ X(void*, void*, std::size_t) { }
+};
+
+void
+test_pr90389()
+{
+ const int n = 3;
+ std::deque<X> d(n);
+ d.emplace(d.begin(), nullptr, nullptr, d.size());
+ VERIFY( d.size() == n+1 );
+}
+
+struct Y
+{
+ Y() = default;
+ Y(std::size_t, const Y&) { }
+};
+
+void
+test_pr118079()
+{
+ const int n = 3;
+ std::deque<Y> d(n);
+ const Y y{};
+ d.emplace(d.begin(), d.size(), y);
+ VERIFY( d.size() == n+1 );
+}
+
+int main()
+{
+ test_pr90389();
+ test_pr118079();
+}