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();
+}

Reply via email to