https://gcc.gnu.org/g:86700d114498ef6ed1f14b54732ba62c9f9504d4
commit r13-9467-g86700d114498ef6ed1f14b54732ba62c9f9504d4 Author: Jonathan Wakely <jwak...@redhat.com> Date: Tue Dec 17 17:38:43 2024 +0000 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. (cherry picked from commit 5f44b1776e748a7528020557036740905a11b1df) Diff: --- libstdc++-v3/include/bits/deque.tcc | 6 +-- libstdc++-v3/include/bits/stl_deque.h | 6 ++- .../23_containers/deque/modifiers/emplace/90389.cc | 43 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index 45a6feebe991..4bc4587be19e 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 685ce43992a6..b1e485b1db57 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -2054,9 +2054,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 000000000000..b4932498700b --- /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(); +}