aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2017-02-06 13:25:57 +0100
committerYvan Roux <yvan.roux@linaro.org>2017-02-06 13:25:57 +0100
commitaad858c02179d21167c43b18b31b3e8008dae1ed (patch)
tree78f5e2544647f1c1c644c0b5e999d8b97467acfb /libstdc++-v3
parentb300ea83b9875ebfafb5f2d652d6eb7c3a57c497 (diff)
Merge branches/gcc-6-branch rev 245201.
Change-Id: Ibc46d8742ef080683f302f5623b4907e9622ac4c
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog68
-rw-r--r--libstdc++-v3/doc/xml/faq.xml2
-rw-r--r--libstdc++-v3/doc/xml/manual/abi.xml6
-rw-r--r--libstdc++-v3/include/bits/basic_string.h23
-rw-r--r--libstdc++-v3/include/bits/list.tcc77
-rw-r--r--libstdc++-v3/include/bits/predefined_ops.h14
-rw-r--r--libstdc++-v3/include/experimental/array12
-rw-r--r--libstdc++-v3/include/std/tuple8
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/cons/allocator_with_any.cc42
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc37
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc37
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/operations/78389.cc74
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search/78346.cc118
-rw-r--r--libstdc++-v3/testsuite/experimental/array/make_array.cc18
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_allocator.h2
15 files changed, 480 insertions, 58 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 61aea40ca75..8785436171c 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,71 @@
+2017-02-01 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/78346
+ * include/bits/predefined_ops.h (_Iter_equals_iter): Store iterator
+ not its referent.
+ (_Iter_comp_to_iter): Likewise.
+ * testsuite/25_algorithms/search/78346.cc: New test.
+
+ PR libstdc++/79195
+ * include/experimental/array (make_array): Use common_type<_Dest>
+ and delay instantiation of common_type until after conditional_t.
+ Qualify std::forward call.
+ (to_array): Add exception specification.
+ * testsuite/experimental/array/make_array.cc: Test argument types
+ without a common type.
+
+ PR libstdc++/79254
+ * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI]
+ (basic_string::operator=(const basic_string&)): If source object is
+ small just deallocate, otherwise perform new allocation before
+ making any changes.
+ * testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc:
+ Test exception-safety of copy assignment when allocator propagates.
+ * testsuite/21_strings/basic_string/allocator/char/copy_assign.cc:
+ Likewise.
+ * testsuite/util/testsuite_allocator.h (uneq_allocator::swap): Make
+ std::swap visible.
+
+2017-01-22 Gerald Pfeifer <gerald@pfeifer.com>
+
+ Backport from mainline
+ 2017-01-01 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/xml/faq.xml: Update address of C++ ABI link.
+ * doc/xml/manual/abi.xml: Ditto.
+
+2017-01-16 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Backport from mainline
+ 2017-01-16 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/78389
+ * include/bits/list.tcc (merge(list&&)): Fix backwards size adjustments.
+ (merge(list&&, _StrictWeakOrdering)): Likewise.
+ * testsuite/23_containers/list/operations/78389.cc: Add
+ better test for the sizes.
+
+2017-01-15 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Backport from mainline
+ 2017-01-13 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/78389
+ * include/bits/list.tcc (merge(list&&)):
+ Adjust list sizes if the comparator throws.
+ (merge(list&&, _StrictWeakOrdering)): Likewise.
+ * testsuite/23_containers/list/operations/78389.cc: New.
+
+2017-01-15 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Backport from mainline
+ 2016-12-19 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Make the perfect-forwarding constructor of a two-element tuple
+ sfinae away when the first argument is an allocator_arg.
+ * include/std/tuple (tuple(_U1&&, _U2&&)): Constrain.
+ * testsuite/20_util/tuple/cons/allocator_with_any.cc: New.
+
2017-01-06 Jonathan Wakely <jwakely@redhat.com>
Backport from mainline
diff --git a/libstdc++-v3/doc/xml/faq.xml b/libstdc++-v3/doc/xml/faq.xml
index b24ee228894..57d9f52c12a 100644
--- a/libstdc++-v3/doc/xml/faq.xml
+++ b/libstdc++-v3/doc/xml/faq.xml
@@ -1230,7 +1230,7 @@
details than for C, and most CPU designers (for good reasons elaborated
below) have not stepped up to publish C++ ABIs. Such an ABI has been
defined for the Itanium architecture (see
- <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.codesourcery.com/cxx-abi/">C++
+ <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mentorembedded.github.io/cxx-abi/">C++
ABI for Itanium</link>) and that is used by G++ and other compilers
as the de facto standard ABI on many common architectures (including x86).
G++ can also use the ARM architecture's EABI, for embedded
diff --git a/libstdc++-v3/doc/xml/manual/abi.xml b/libstdc++-v3/doc/xml/manual/abi.xml
index aa5aa5be07d..8636124cbb7 100644
--- a/libstdc++-v3/doc/xml/manual/abi.xml
+++ b/libstdc++-v3/doc/xml/manual/abi.xml
@@ -42,7 +42,7 @@
virtual functions, etc. These details are defined as the compiler
Application Binary Interface, or ABI. The GNU C++ compiler uses an
industry-standard C++ ABI starting with version 3. Details can be
- found in the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mentorembedded.github.com/cxx-abi/abi.html">ABI
+ found in the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mentorembedded.github.io/cxx-abi/abi.html">ABI
specification</link>.
</para>
@@ -736,7 +736,7 @@ class that would otherwise have implicit versions. This will change
the way the compiler deals with this class in by-value return
statements or parameters: instead of passing instances of this
class in registers, the compiler will be forced to use memory. See the
-section on <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mentorembedded.github.com/cxx-abi/abi.html#calls">Function
+section on <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mentorembedded.github.io/cxx-abi/abi.html#calls">Function
Calling Conventions and APIs</link>
of the C++ ABI documentation for further details.
</para></listitem>
@@ -1094,7 +1094,7 @@ gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.
<biblioentry xml:id="biblio.cxxabi">
<title>
<link xmlns:xlink="http://www.w3.org/1999/xlink"
- xlink:href="http://www.codesourcery.com/cxx-abi/">
+ xlink:href="http://mentorembedded.github.io/cxx-abi/">
C++ ABI Summary
</link>
</title>
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index f8f3f88cc56..0352bf49fdc 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -570,10 +570,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
&& _M_get_allocator() != __str._M_get_allocator())
{
- // replacement allocator cannot free existing storage
- _M_destroy(_M_allocated_capacity);
- _M_data(_M_local_data());
- _M_set_length(0);
+ // Propagating allocator cannot free existing storage so must
+ // deallocate it before replacing current allocator.
+ if (__str.size() <= _S_local_capacity)
+ {
+ _M_destroy(_M_allocated_capacity);
+ _M_data(_M_local_data());
+ _M_set_length(0);
+ }
+ else
+ {
+ const auto __len = __str.size();
+ auto __alloc = __str._M_get_allocator();
+ // If this allocation throws there are no effects:
+ auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1);
+ _M_destroy(_M_allocated_capacity);
+ _M_data(__ptr);
+ _M_capacity(__len);
+ _M_set_length(__len);
+ }
}
std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
}
diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc
index 8b3fe00cfcd..81b8be2a61e 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -380,26 +380,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// 300. list::merge() specification incomplete
if (this != std::__addressof(__x))
{
- _M_check_equal_allocators(__x);
+ _M_check_equal_allocators(__x);
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
- while (__first1 != __last1 && __first2 != __last2)
- if (*__first2 < *__first1)
- {
- iterator __next = __first2;
- _M_transfer(__first1, __first2, ++__next);
- __first2 = __next;
- }
- else
- ++__first1;
- if (__first2 != __last2)
- _M_transfer(__last1, __first2, __last2);
+ size_t __orig_size = __x.size();
+ __try {
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first2 < *__first1)
+ {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2)
+ _M_transfer(__last1, __first2, __last2);
- this->_M_inc_size(__x._M_get_size());
- __x._M_set_size(0);
+ this->_M_inc_size(__x._M_get_size());
+ __x._M_set_size(0);
+ }
+ __catch(...)
+ {
+ size_t __dist = distance(__first2, __last2);
+ this->_M_inc_size(__orig_size - __dist);
+ __x._M_set_size(__dist);
+ __throw_exception_again;
+ }
}
}
@@ -423,20 +433,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
- while (__first1 != __last1 && __first2 != __last2)
- if (__comp(*__first2, *__first1))
- {
- iterator __next = __first2;
- _M_transfer(__first1, __first2, ++__next);
- __first2 = __next;
- }
- else
- ++__first1;
- if (__first2 != __last2)
- _M_transfer(__last1, __first2, __last2);
-
- this->_M_inc_size(__x._M_get_size());
- __x._M_set_size(0);
+ size_t __orig_size = __x.size();
+ __try
+ {
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp(*__first2, *__first1))
+ {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2)
+ _M_transfer(__last1, __first2, __last2);
+
+ this->_M_inc_size(__x._M_get_size());
+ __x._M_set_size(0);
+ }
+ __catch(...)
+ {
+ size_t __dist = distance(__first2, __last2);
+ this->_M_inc_size(__orig_size - __dist);
+ __x._M_set_size(__dist);
+ __throw_exception_again;
+ }
}
}
diff --git a/libstdc++-v3/include/bits/predefined_ops.h b/libstdc++-v3/include/bits/predefined_ops.h
index d254795c1a5..7f4bfe65f31 100644
--- a/libstdc++-v3/include/bits/predefined_ops.h
+++ b/libstdc++-v3/include/bits/predefined_ops.h
@@ -24,7 +24,7 @@
/** @file predefined_ops.h
* This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
+ * You should not attempt to use it directly. @headername{algorithm}
*/
#ifndef _GLIBCXX_PREDEFINED_OPS_H
@@ -207,17 +207,17 @@ namespace __ops
template<typename _Iterator1>
struct _Iter_equals_iter
{
- typename std::iterator_traits<_Iterator1>::reference _M_ref;
+ _Iterator1 _M_it1;
explicit
_Iter_equals_iter(_Iterator1 __it1)
- : _M_ref(*__it1)
+ : _M_it1(__it1)
{ }
template<typename _Iterator2>
bool
operator()(_Iterator2 __it2)
- { return *__it2 == _M_ref; }
+ { return *__it2 == *_M_it1; }
};
template<typename _Iterator>
@@ -271,16 +271,16 @@ namespace __ops
struct _Iter_comp_to_iter
{
_Compare _M_comp;
- typename std::iterator_traits<_Iterator1>::reference _M_ref;
+ _Iterator1 _M_it1;
_Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1)
- : _M_comp(__comp), _M_ref(*__it1)
+ : _M_comp(__comp), _M_it1(__it1)
{ }
template<typename _Iterator2>
bool
operator()(_Iterator2 __it2)
- { return bool(_M_comp(*__it2, _M_ref)); }
+ { return bool(_M_comp(*__it2, *_M_it1)); }
};
template<typename _Compare, typename _Iterator>
diff --git a/libstdc++-v3/include/experimental/array b/libstdc++-v3/include/experimental/array
index 31a066b3ce8..c01f0f96ab5 100644
--- a/libstdc++-v3/include/experimental/array
+++ b/libstdc++-v3/include/experimental/array
@@ -69,9 +69,9 @@ template <typename _Up>
template <typename _Dest = void, typename... _Types>
constexpr auto
make_array(_Types&&... __t)
- -> array<conditional_t<is_void_v<_Dest>,
- common_type_t<_Types...>,
- _Dest>,
+ -> array<typename conditional_t<is_void_v<_Dest>,
+ common_type<_Types...>,
+ common_type<_Dest>>::type,
sizeof...(_Types)>
{
static_assert(__or_<
@@ -80,13 +80,12 @@ template <typename _Dest = void, typename... _Types>
::value,
"make_array cannot be used without an explicit target type "
"if any of the types given is a reference_wrapper");
- return {{forward<_Types>(__t)...}};
+ return {{ std::forward<_Types>(__t)... }};
}
template <typename _Tp, size_t _Nm, size_t... _Idx>
constexpr array<remove_cv_t<_Tp>, _Nm>
- __to_array(_Tp (&__a)[_Nm],
- index_sequence<_Idx...>)
+ __to_array(_Tp (&__a)[_Nm], index_sequence<_Idx...>)
{
return {{__a[_Idx]...}};
}
@@ -94,6 +93,7 @@ template <typename _Tp, size_t _Nm, size_t... _Idx>
template <typename _Tp, size_t _Nm>
constexpr array<remove_cv_t<_Tp>, _Nm>
to_array(_Tp (&__a)[_Nm])
+ noexcept(is_nothrow_constructible<remove_cv_t<_Tp>, _Tp&>::value)
{
return __to_array(__a, make_index_sequence<_Nm>{});
}
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 7522e435184..ec269c1a8d7 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -923,7 +923,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
enable_if<_TMC::template
_MoveConstructibleTuple<_U1, _U2>()
&& _TMC::template
- _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
+ _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
+ && !is_same<typename decay<_U1>::type,
+ allocator_arg_t>::value,
bool>::type = true>
constexpr tuple(_U1&& __a1, _U2&& __a2)
: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
@@ -932,7 +934,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
enable_if<_TMC::template
_MoveConstructibleTuple<_U1, _U2>()
&& !_TMC::template
- _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
+ _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
+ && !is_same<typename decay<_U1>::type,
+ allocator_arg_t>::value,
bool>::type = false>
explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/allocator_with_any.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/allocator_with_any.cc
new file mode 100644
index 00000000000..9f86c93e378
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/allocator_with_any.cc
@@ -0,0 +1,42 @@
+// { dg-do run { target c++14 } }
+
+// 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/>.
+
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on tuple. If the implementation changed
+// this test may begin to fail.
+
+#include <tuple>
+#include <experimental/any>
+#include <testsuite_hooks.h>
+
+using std::experimental::any;
+
+void test01()
+{
+ std::tuple<any, any> t(std::allocator_arg,
+ std::allocator<any>{});
+ VERIFY(std::get<0>(t).empty());
+ VERIFY(std::get<1>(t).empty());
+}
+
+int main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
index 3c8e440120e..645e3cb7bfe 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2016 Free Software Foundation, Inc.
+// Copyright (C) 2015-2017 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
@@ -20,6 +20,7 @@
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
+#include <ext/throw_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = char;
@@ -100,10 +101,44 @@ void test02()
VERIFY(1 == v5.get_allocator().get_personality());
}
+void test03()
+{
+ // PR libstdc++/79254
+ using throw_alloc = __gnu_cxx::throw_allocator_limit<C>;
+ typedef propagating_allocator<C, true, throw_alloc> alloc_type;
+ typedef std::basic_string<C, traits, alloc_type> test_type;
+ alloc_type a1(1), a2(2);
+ throw_alloc::set_limit(2); // Throw on third allocation (during assignment).
+ const C* s1 = "a string that is longer than a small string";
+ const C* s2 = "another string that is longer than a small string";
+ test_type v1(s1, a1);
+ test_type v2(s2, a2);
+ bool caught = false;
+ try {
+ v1 = v2;
+ } catch (__gnu_cxx::forced_error&) {
+ caught = true;
+ }
+ VERIFY( caught );
+ VERIFY( v1 == s1 );
+ VERIFY( v1.get_allocator() == a1 );
+
+ throw_alloc::set_limit(1); // Allow one more allocation (and no more).
+ test_type v3(s1, a1);
+ // No allocation when allocators are equal and capacity is sufficient:
+ VERIFY( v1.capacity() >= v3.size() );
+ v1 = v3;
+ // No allocation when the contents fit in the small-string buffer:
+ v2 = "sso";
+ v1 = v2;
+ VERIFY( v1.get_allocator() == a2 );
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
#else
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
index 3ac15bbf821..01cdba4eead 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2016 Free Software Foundation, Inc.
+// Copyright (C) 2015-2017 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
@@ -20,6 +20,7 @@
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
+#include <ext/throw_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = wchar_t;
@@ -100,10 +101,44 @@ void test02()
VERIFY(1 == v5.get_allocator().get_personality());
}
+void test03()
+{
+ // PR libstdc++/79254
+ using throw_alloc = __gnu_cxx::throw_allocator_limit<C>;
+ typedef propagating_allocator<C, true, throw_alloc> alloc_type;
+ typedef std::basic_string<C, traits, alloc_type> test_type;
+ alloc_type a1(1), a2(2);
+ throw_alloc::set_limit(2); // Throw on third allocation (during assignment).
+ const C* s1 = L"a string that is longer than a small string";
+ const C* s2 = L"another string that is longer than a small string";
+ test_type v1(s1, a1);
+ test_type v2(s2, a2);
+ bool caught = false;
+ try {
+ v1 = v2;
+ } catch (__gnu_cxx::forced_error&) {
+ caught = true;
+ }
+ VERIFY( caught );
+ VERIFY( v1 == s1 );
+ VERIFY( v1.get_allocator() == a1 );
+
+ throw_alloc::set_limit(1); // Allow one more allocation (and no more).
+ test_type v3(s1, a1);
+ // No allocation when allocators are equal and capacity is sufficient:
+ VERIFY( v1.capacity() >= v3.size() );
+ v1 = v3;
+ // No allocation when the contents fit in the small-string buffer:
+ v2 = L"sso";
+ v1 = v2;
+ VERIFY( v1.get_allocator() == a2 );
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
#else
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/78389.cc b/libstdc++-v3/testsuite/23_containers/list/operations/78389.cc
new file mode 100644
index 00000000000..ac36f9c94d8
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/78389.cc
@@ -0,0 +1,74 @@
+// { dg-do run { target c++11 } }
+
+// Copyright (C) 2017 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/>.
+
+// 23.2.2.4 list operations [lib.list.ops]
+
+#include <testsuite_hooks.h>
+
+#include <list>
+
+struct ThrowingComparator
+{
+ unsigned int throw_after = 0;
+ unsigned int count = 0;
+ bool operator()(int, int) {
+ if (++count >= throw_after) {
+ throw 666;
+ }
+ return true;
+ }
+};
+
+struct X
+{
+ X() = default;
+ X(int) {}
+};
+
+unsigned int throw_after_X = 0;
+unsigned int count_X = 0;
+
+bool operator<(const X&, const X&) {
+ if (++count_X >= throw_after_X) {
+ throw 666;
+ }
+ return true;
+}
+
+
+int main()
+{
+ std::list<int> a{1, 2, 3, 4};
+ std::list<int> b{5, 6, 7, 8, 9, 10, 11, 12};
+ try {
+ a.merge(b, ThrowingComparator{4});
+ } catch (...) {
+ }
+ VERIFY(a.size() == std::distance(a.begin(), a.end()) &&
+ b.size() == std::distance(b.begin(), b.end()));
+ std::list<X> ax{1, 2, 3, 4};
+ std::list<X> bx{5, 6, 7, 8, 9, 10, 11, 12};
+ throw_after_X = 4;
+ try {
+ ax.merge(bx);
+ } catch (...) {
+ }
+ VERIFY(ax.size() == std::distance(ax.begin(), ax.end()) &&
+ bx.size() == std::distance(bx.begin(), bx.end()));
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/search/78346.cc b/libstdc++-v3/testsuite/25_algorithms/search/78346.cc
new file mode 100644
index 00000000000..6f003bdb9e6
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/search/78346.cc
@@ -0,0 +1,118 @@
+// Copyright (C) 2017 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-do run { target c++11 } }
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+bool values[100];
+
+unsigned next_id()
+{
+ static unsigned counter = 0;
+ VERIFY(counter < 100);
+ return counter++;
+}
+
+struct value
+{
+ int val;
+ const unsigned id;
+
+ value(int i = 0) : val(i), id(next_id()) { values[id] = true; }
+ value(const value& v) : val(v.val), id(next_id()) { values[id] = true; }
+ value& operator=(const value& v) { val = v.val; return *this; }
+ ~value() { values[id] = false; }
+};
+
+bool operator<(const value& lhs, const value& rhs)
+{
+ if (!values[lhs.id])
+ throw lhs.id;
+ if (!values[rhs.id])
+ throw rhs.id;
+ return lhs.val < rhs.val;
+}
+
+bool operator==(const value& lhs, const value& rhs)
+{
+ if (!values[lhs.id])
+ throw lhs.id;
+ if (!values[rhs.id])
+ throw rhs.id;
+ return lhs.val == rhs.val;
+}
+
+// A forward iterator that fails to meet the requirement that for any
+// two dereferenceable forward iterators, a == b implies &*a == &*b
+struct stashing_iterator
+{
+ typedef std::forward_iterator_tag iterator_category;
+ typedef value value_type;
+ typedef value_type const* pointer;
+ typedef value_type const& reference;
+ typedef std::ptrdiff_t difference_type;
+
+ stashing_iterator() : ptr(), stashed() { }
+ stashing_iterator(pointer p) : ptr(p), stashed() { stash(); }
+ stashing_iterator(const stashing_iterator&) = default;
+ stashing_iterator& operator=(const stashing_iterator&) = default;
+
+ stashing_iterator& operator++()
+ {
+ ++ptr;
+ stash();
+ return *this;
+ }
+
+ stashing_iterator operator++(int)
+ {
+ stashing_iterator i = *this;
+ ++*this;
+ return i;
+ }
+
+ reference operator*() const { return stashed; }
+ pointer operator->() const { return &**this; }
+
+ bool operator==(const stashing_iterator& i) const { return ptr == i.ptr; }
+ bool operator!=(const stashing_iterator& i) const { return !(*this == i); }
+
+private:
+ void stash()
+ {
+ if (ptr)
+ stashed = *ptr;
+ }
+
+ pointer ptr;
+ value_type stashed;
+};
+
+void
+test01()
+{
+ value s[] = { 0, 1, 2, 3, 4, 5 };
+ std::search(s, s+6, stashing_iterator(s), stashing_iterator(s+4));
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/experimental/array/make_array.cc b/libstdc++-v3/testsuite/experimental/array/make_array.cc
index 0ae188b0f8b..75f5333639c 100644
--- a/libstdc++-v3/testsuite/experimental/array/make_array.cc
+++ b/libstdc++-v3/testsuite/experimental/array/make_array.cc
@@ -1,7 +1,6 @@
-// { dg-options "-std=gnu++14" }
-// { dg-do compile }
+// { dg-do compile { target c++14 } }
-// Copyright (C) 2015-2016 Free Software Foundation, Inc.
+// Copyright (C) 2015-2017 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
@@ -19,6 +18,7 @@
// <http://www.gnu.org/licenses/>.
#include <experimental/array>
+#include <functional> // for std::ref and std::reference_wrapper
struct MoveOnly
{
@@ -27,7 +27,7 @@ struct MoveOnly
MoveOnly& operator=(MoveOnly&&) = default;
};
-int main()
+void test01()
{
char x[42];
std::array<char, 42> y = std::experimental::to_array(x);
@@ -45,3 +45,13 @@ int main()
= std::experimental::make_array(1,2L, 3);
constexpr std::array<MoveOnly, 1> zzz2 = std::experimental::make_array(MoveOnly{});
}
+
+void test02()
+{
+ // PR libstdc++/79195
+ struct A {};
+ struct B : A {};
+ struct C : A {};
+ auto arr = std::experimental::make_array<A>(B{}, C{});
+ static_assert(std::is_same<decltype(arr), std::array<A, 2>>::value, "");
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index 4884600bcb8..f597a3846ab 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -287,7 +287,7 @@ namespace __gnu_test
Alloc& base() { return *this; }
const Alloc& base() const { return *this; }
- void swap_base(Alloc& b) { swap(b, this->base()); }
+ void swap_base(Alloc& b) { using std::swap; swap(b, this->base()); }
public:
typedef typename check_consistent_alloc_value_type<Tp, Alloc>::value_type