diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2017-02-06 13:25:57 +0100 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2017-02-06 13:25:57 +0100 |
commit | aad858c02179d21167c43b18b31b3e8008dae1ed (patch) | |
tree | 78f5e2544647f1c1c644c0b5e999d8b97467acfb /libstdc++-v3 | |
parent | b300ea83b9875ebfafb5f2d652d6eb7c3a57c497 (diff) |
Merge branches/gcc-6-branch rev 245201.
Change-Id: Ibc46d8742ef080683f302f5623b4907e9622ac4c
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 68 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/faq.xml | 2 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/manual/abi.xml | 6 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/basic_string.h | 23 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/list.tcc | 77 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/predefined_ops.h | 14 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/array | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/std/tuple | 8 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/cons/allocator_with_any.cc | 42 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc | 37 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc | 37 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/list/operations/78389.cc | 74 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/25_algorithms/search/78346.cc | 118 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/array/make_array.cc | 18 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/util/testsuite_allocator.h | 2 |
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 |