This is a very simple change, to allow conversions that are supposed
to be valid according to DR 2118. The fix was slightly complicated by
the tests being a bit of a mess. We had tests for this requirement,
but they were in files which mixed positive tests and negative tests.
I've split the tests so the invalid operations are in separate files
and all the valid operations are in files that should pass.
PR libstdc++/77987
* include/bits/unique_ptr.h (unique_ptr<T[], D>::reset<U>(U)): Copy
value to pointer of the correct type to swap, to support conversions
allowed by LWG 2118 / N4089.
* testsuite/20_util/unique_ptr/assign/assign_neg.cc: Move test for
incompatible deleters from ...
* testsuite/20_util/unique_ptr/assign/cv_qual.cc: ... here.
* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Move tests for
incompatible pointers to ...
* testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: ... here. Move
destructor definition to base class. Test for invalid derived-to-base
conversion.
I'll also backport this to the branches.
commit 2e75149f402d242310ba53b8d31ef38df0d17ed1
Author: Jonathan Wakely <[email protected]>
Date: Sat Oct 15 19:06:09 2016 +0100
PR77987 Fix unique_ptr<T[], D>::reset(U) for T != U
PR libstdc++/77987
* include/bits/unique_ptr.h (unique_ptr<T[], D>::reset<U>(U)): Copy
value to pointer of the correct type to swap, to support conversions
allowed by LWG 2118 / N4089.
* testsuite/20_util/unique_ptr/assign/assign_neg.cc: Move test for
incompatible deleters from ...
* testsuite/20_util/unique_ptr/assign/cv_qual.cc: ... here.
* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Move tests for
incompatible pointers to ...
* testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: ... here. Move
destructor definition to base class. Test for invalid derived-to-base
conversion.
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index 15ef8a8..a36794d 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -610,10 +610,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
reset(_Up __p) noexcept
{
+ pointer __ptr = __p;
using std::swap;
- swap(std::get<0>(_M_t), __p);
- if (__p != nullptr)
- get_deleter()(__p);
+ swap(std::get<0>(_M_t), __ptr);
+ if (__ptr != nullptr)
+ get_deleter()(__ptr);
}
void reset(nullptr_t = nullptr) noexcept
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
index 842b6ed..9142e61 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
@@ -48,4 +48,25 @@ test03()
std::unique_ptr<int[2]> p2 = p1; // { dg-error "deleted" }
}
+struct base_pointer { operator base*() const { return nullptr; } };
+
+template<typename T>
+struct deleter
+{
+ deleter() = default;
+ template<typename U>
+ deleter(const deleter<U>) { }
+ typedef T pointer;
+ void operator()(T) const { }
+};
+
+void
+test04()
+{
+ // Disallow conversions from incompatible deleter
+ std::unique_ptr<derived[], deleter<base_pointer>> p;
+ std::unique_ptr<base[], deleter<base*>> upA;
+ upA = std::move(p); // { dg-error "no match" }
+}
+
// { dg-prune-output "include" }
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
index 793499d..7add5a9 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
@@ -65,26 +65,3 @@ test03()
std::unique_ptr<const volatile A[]> cvA;
cvA = std::move(upA);
}
-
-struct A_pointer { operator A*() const { return nullptr; } };
-
-template<typename T>
-struct deleter
-{
- deleter() = default;
- template<typename U>
- deleter(const deleter<U>) { }
- typedef T pointer;
- void operator()(T) const { }
-};
-
-void
-test04()
-{
- // Disallow conversions from incompatible deleter
- std::unique_ptr<B[], deleter<A_pointer>> p;
- std::unique_ptr<A[], deleter<A*>> upA;
- upA = std::move(p); // { dg-error "no match" }
- // { dg-error "no type" "" { target *-*-* } 537 }
- // { dg-error "no matching function" "" { target *-*-* } 614 }
-}
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
index 0284563..f92949b 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
@@ -86,15 +86,4 @@ test07()
vA2.reset((A*)p);
std::unique_ptr<const volatile A[]> cvA2;
cvA2.reset((A*)p);
- // Disallow conversions from user-defined pointer-like types
- // for the array version
- std::unique_ptr<A[]> upA3;
- upA3.reset(p); // { dg-error "no matching function" }
- std::unique_ptr<const A[]> cA3;
- cA3.reset(p); // { dg-error "no matching function" }
- std::unique_ptr<volatile A[]> vA3;
- vA3.reset(p); // { dg-error "no matching function" }
- std::unique_ptr<const volatile A[]> cvA3;
- cvA3.reset(p); // { dg-error "no matching function" }
- // { dg-error "no matching function" "" { target *-*-* } 614 }
}
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
index d2ed03c..cb5f2e6 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
@@ -21,17 +21,37 @@
struct A
{
+ virtual ~A() { }
};
struct B : A
{
- virtual ~B() { }
};
-void test01()
+void
+test01()
{
std::unique_ptr<B[]> up;
- up.reset(new A[3]); // { dg-error "" }
+ up.reset(new A[3]); // { dg-error "no matching function" }
+
+ std::unique_ptr<A[]> up2;
+ up2.reset(new B[3]); // { dg-error "no matching function" }
}
-// { dg-prune-output "include" }
+struct A_pointer { operator A*() const { return nullptr; } };
+
+void
+test02()
+{
+ A_pointer p;
+ // Disallow conversions from user-defined pointer-like types
+ // for the array version
+ std::unique_ptr<A[]> upA3;
+ upA3.reset(p); // { dg-error "no matching function" }
+ std::unique_ptr<const A[]> cA3;
+ cA3.reset(p); // { dg-error "no matching function" }
+ std::unique_ptr<volatile A[]> vA3;
+ vA3.reset(p); // { dg-error "no matching function" }
+ std::unique_ptr<const volatile A[]> cvA3;
+ cvA3.reset(p); // { dg-error "no matching function" }
+}
commit 8e8e806cbdd4581331364153d69d39b5765f8343
Author: Jonathan Wakely <[email protected]>
Date: Sat Oct 15 18:56:24 2016 +0100
Implement P0084R2, Emplace return type, for C++17
* doc/xml/manual/status_cxx2017.xml: Update status.
* doc/html/*: Regenerate.
* include/bits/deque.tcc (deque::emplace_front, deque::emplace_back):
Return a reference in C++17 mode.
* include/bits/forward_list.h (forward_list::emplace_front): Likewise.
* include/bits/stl_bvector.h (vector<bool>::emplace_back): Likewise.
* include/bits/stl_deque.h (deque::emplace_front, deque::emplace_back):
Likewise.
* include/bits/stl_list.h (list::emplace_front, list::emplace_back):
Likewise.
* include/bits/stl_queue.h (queue::emplace): Likewise.
* include/bits/stl_stack.h (stack::emplace): Likewise.
* include/bits/stl_vector.h (vector::emplace_back): Likewise.
* include/bits/vector.tcc (vector::emplace_back): Likewise.
* include/debug/deque (__gnu_debug::deque::emplace_front)
(__gnu_debug::deque::emplace_back): Likewise.
* include/debug/vector (__gnu_debug::vector::emplace_back): Likewise.
* testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc:
New.
* testsuite/23_containers/forward_list/modifiers/
emplace_cxx17_return.cc: New.
* testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc: New.
* testsuite/23_containers/queue/members/emplace_cxx17_return.cc: New.
* testsuite/23_containers/stack/members/emplace_cxx17_return.cc: New.
* testsuite/23_containers/vector/bool/emplace_cxx17_return.cc: New.
* testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc:
New.
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index ae8dfa9..a1190bc 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -542,14 +542,13 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Emplace return type </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0084r2.pdf">
P0084R2
</link>
</entry>
- <entry align="center"> No </entry>
+ <entry align="center"> 7 </entry>
<entry/>
</row>
diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc
index 96ec9f8..796b0cd 100644
--- a/libstdc++-v3/include/bits/deque.tcc
+++ b/libstdc++-v3/include/bits/deque.tcc
@@ -129,7 +129,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
template<typename... _Args>
+#if __cplusplus > 201402L
+ typename deque<_Tp, _Alloc>::reference
+#else
void
+#endif
deque<_Tp, _Alloc>::
emplace_front(_Args&&... __args)
{
@@ -142,11 +146,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
else
_M_push_front_aux(std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return front();
+#endif
}
template<typename _Tp, typename _Alloc>
template<typename... _Args>
+#if __cplusplus > 201402L
+ typename deque<_Tp, _Alloc>::reference
+#else
void
+#endif
deque<_Tp, _Alloc>::
emplace_back(_Args&&... __args)
{
@@ -160,6 +171,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
else
_M_push_back_aux(std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return back();
+#endif
}
#endif
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 3961509..0ea8806 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -797,10 +797,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* and references.
*/
template<typename... _Args>
- void
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
emplace_front(_Args&&... __args)
- { this->_M_insert_after(cbefore_begin(),
- std::forward<_Args>(__args)...); }
+ {
+ this->_M_insert_after(cbefore_begin(),
+ std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return front();
+#endif
+ }
/**
* @brief Add data to the front of the %forward_list.
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index b3ac63f..2e231b9 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1056,9 +1056,18 @@ template<typename _Alloc>
#if __cplusplus >= 201103L
template<typename... _Args>
+#if __cplusplus > 201402L
+ reference
+#else
void
+#endif
emplace_back(_Args&&... __args)
- { push_back(bool(__args...)); }
+ {
+ push_back(bool(__args...));
+#if __cplusplus > 201402L
+ return back();
+#endif
+ }
template<typename... _Args>
iterator
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 7192f65..8539a08 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -1519,7 +1519,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ emplace_front(std::move(__x)); }
template<typename... _Args>
- void
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
emplace_front(_Args&&... __args);
#endif
@@ -1552,7 +1556,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ emplace_back(std::move(__x)); }
template<typename... _Args>
- void
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
emplace_back(_Args&&... __args);
#endif
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index 87c8a39..8693a6f 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1069,9 +1069,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ this->_M_insert(begin(), std::move(__x)); }
template<typename... _Args>
- void
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
emplace_front(_Args&&... __args)
- { this->_M_insert(begin(), std::forward<_Args>(__args)...); }
+ {
+ this->_M_insert(begin(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return front();
+#endif
+ }
#endif
/**
@@ -1110,9 +1119,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ this->_M_insert(end(), std::move(__x)); }
template<typename... _Args>
- void
+#if __cplusplus > 201402L
+ reference
+#else
+ void
+#endif
emplace_back(_Args&&... __args)
- { this->_M_insert(end(), std::forward<_Args>(__args)...); }
+ {
+ this->_M_insert(end(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return back();
+#endif
+ }
#endif
/**
diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h
index 843199c..178e4b2 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -247,11 +247,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
push(value_type&& __x)
{ c.push_back(std::move(__x)); }
+#if __cplusplus > 201402L
+ template<typename... _Args>
+ decltype(auto)
+ emplace(_Args&&... __args)
+ { return c.emplace_back(std::forward<_Args>(__args)...); }
+#else
template<typename... _Args>
void
emplace(_Args&&... __args)
{ c.emplace_back(std::forward<_Args>(__args)...); }
#endif
+#endif
/**
* @brief Removes first element.
diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h
index 612913d..ebc8816 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -223,11 +223,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
push(value_type&& __x)
{ c.push_back(std::move(__x)); }
+#if __cplusplus > 201402L
+ template<typename... _Args>
+ decltype(auto)
+ emplace(_Args&&... __args)
+ { return c.emplace_back(std::forward<_Args>(__args)...); }
+#else
template<typename... _Args>
void
emplace(_Args&&... __args)
{ c.emplace_back(std::forward<_Args>(__args)...); }
#endif
+#endif
/**
* @brief Removes first element.
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 9a05dd5..efc569b 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -960,7 +960,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ emplace_back(std::move(__x)); }
template<typename... _Args>
+#if __cplusplus > 201402L
+ reference
+#else
void
+#endif
emplace_back(_Args&&... __args);
#endif
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 6926a8b..b6050d3 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -87,7 +87,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
template<typename... _Args>
+#if __cplusplus > 201402L
+ typename vector<_Tp, _Alloc>::reference
+#else
void
+#endif
vector<_Tp, _Alloc>::
emplace_back(_Args&&... __args)
{
@@ -99,6 +103,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
else
_M_realloc_insert(end(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+ return back();
+#endif
}
#endif
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index f15faad..bf4cba6 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -386,19 +386,33 @@ namespace __debug
{ emplace_back(std::move(__x)); }
template<typename... _Args>
+#if __cplusplus > 201402L
+ reference
+#else
void
+#endif
emplace_front(_Args&&... __args)
{
_Base::emplace_front(std::forward<_Args>(__args)...);
this->_M_invalidate_all();
+#if __cplusplus > 201402L
+ return front();
+#endif
}
template<typename... _Args>
+#if __cplusplus > 201402L
+ reference
+#else
void
+#endif
emplace_back(_Args&&... __args)
{
_Base::emplace_back(std::forward<_Args>(__args)...);
this->_M_invalidate_all();
+#if __cplusplus > 201402L
+ return back();
+#endif
}
template<typename... _Args>
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 9bcda73..b2d70bd 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -478,7 +478,11 @@ namespace __debug
{ emplace_back(std::move(__x)); }
template<typename... _Args>
+#if __cplusplus > 201402L
+ deque<_Tp, _Alloc>::reference
+#else
void
+#endif
emplace_back(_Args&&... __args)
{
bool __realloc = this->_M_requires_reallocation(this->size() + 1);
@@ -486,6 +490,9 @@ namespace __debug
if (__realloc)
this->_M_invalidate_all();
this->_M_update_guaranteed_capacity();
+#if __cplusplus > 201402L
+ return back();
+#endif
}
#endif
diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc
new file mode 100644
index 0000000..3e5da96
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <deque>
+#include <testsuite_hooks.h>
+
+using test_type = std::deque<int>;
+
+void
+test01()
+{
+ test_type x{1, 2, 3, 4};
+ test_type::reference r = x.emplace_front(0);
+ VERIFY( r == 0 );
+ VERIFY( &r == &x.front() );
+}
+
+void
+test02()
+{
+ test_type x{1, 2, 3, 4};
+ test_type::reference r = x.emplace_back(5);
+ VERIFY( r == 5 );
+ VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/emplace_cxx17_return.cc
new file mode 100644
index 0000000..b91c1ca
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/emplace_cxx17_return.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+
+using test_type = std::forward_list<int>;
+
+void
+test01()
+{
+ test_type x{1, 2, 3, 4};
+ test_type::reference r = x.emplace_front(0);
+ VERIFY( r == 0 );
+ VERIFY( &r == &x.front() );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc
new file mode 100644
index 0000000..c88d8d2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <list>
+#include <testsuite_hooks.h>
+
+using test_type = std::list<int>;
+
+void
+test01()
+{
+ test_type x{1, 2, 3, 4};
+ test_type::reference r = x.emplace_front(0);
+ VERIFY( r == 0 );
+ VERIFY( &r == &x.front() );
+}
+
+void
+test02()
+{
+ test_type x{1, 2, 3, 4};
+ test_type::reference r = x.emplace_back(5);
+ VERIFY( r == 5 );
+ VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/queue/members/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/queue/members/emplace_cxx17_return.cc
new file mode 100644
index 0000000..a618e9c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/queue/members/emplace_cxx17_return.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <queue>
+#include <testsuite_hooks.h>
+
+using test_type = std::queue<int>;
+
+void
+test01()
+{
+ test_type x{ test_type::container_type{1, 2, 3, 4} };
+ test_type::reference r = x.emplace(5);
+ VERIFY( r == 5 );
+ VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/stack/members/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/stack/members/emplace_cxx17_return.cc
new file mode 100644
index 0000000..76964eb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/stack/members/emplace_cxx17_return.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <stack>
+#include <testsuite_hooks.h>
+
+using test_type = std::stack<int>;
+
+void
+test01()
+{
+ test_type x{ test_type::container_type{1, 2, 3, 4} };
+ test_type::reference r = x.emplace(5);
+ VERIFY( r == 5 );
+ VERIFY( &r == &x.top() );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_cxx17_return.cc
new file mode 100644
index 0000000..d4f70fb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_cxx17_return.cc
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+using test_type = std::vector<bool>;
+
+void
+test02()
+{
+ test_type x{true, true};
+ test_type::reference r = x.emplace_back(false);
+ VERIFY( r == false );
+}
+
+int
+main()
+{
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc
new file mode 100644
index 0000000..9006dab
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+using test_type = std::vector<int>;
+
+void
+test02()
+{
+ test_type x{1, 2, 3, 4};
+ test_type::reference r = x.emplace_back(5);
+ VERIFY( r == 5 );
+ VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+ test02();
+}