diff options
Diffstat (limited to 'libstdc++-v3')
| -rw-r--r-- | libstdc++-v3/ChangeLog | 62 | ||||
| -rw-r--r-- | libstdc++-v3/include/bits/regex.tcc | 49 | ||||
| -rw-r--r-- | libstdc++-v3/include/bits/version.def | 9 | ||||
| -rw-r--r-- | libstdc++-v3/include/bits/version.h | 10 | ||||
| -rw-r--r-- | libstdc++-v3/include/std/regex | 1 | ||||
| -rw-r--r-- | libstdc++-v3/include/std/tuple | 53 | ||||
| -rw-r--r-- | libstdc++-v3/include/std/type_traits | 17 | ||||
| -rw-r--r-- | libstdc++-v3/src/c++23/std.cc.in | 4 | ||||
| -rw-r--r-- | libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc | 4 | ||||
| -rw-r--r-- | libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc | 129 | ||||
| -rw-r--r-- | libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc | 27 | ||||
| -rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc | 17 | ||||
| -rw-r--r-- | libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc | 121 | ||||
| -rw-r--r-- | libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc | 29 | ||||
| -rw-r--r-- | libstdc++-v3/testsuite/30_threads/thread/swap/1.cc | 2 | 
15 files changed, 502 insertions, 32 deletions
| diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 77ab059..e270c67 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,65 @@ +2025-10-30  Jakub Jelinek  <jakub@redhat.com> + +	* include/bits/version.def (is_implicit_lifetime): New. +	* include/bits/version.h: Regenerate. +	* include/std/type_traits (std::is_implicit_lifetime, +	std::is_implicit_lifetime_v): New trait. +	* src/c++23/std.cc.in (std::is_implicit_lifetime, +	std::is_implicit_lifetime_v): Export. +	* testsuite/20_util/is_implicit_lifetime/version.cc: New test. +	* testsuite/20_util/is_implicit_lifetime/value.cc: New test. + +2025-10-29  Jonathan Wakely  <jwakely@redhat.com> + +	* include/bits/regex.tcc (regex_traits::value): Use __c instead +	of __ch. + +2025-10-29  Jonathan Wakely  <jwakely@redhat.com> + +	* testsuite/17_intro/headers/c++2011/42319.cc: Include <ios> +	instead of <bits/char_traits.h>. Add no_pch option. Remove +	explicit -std=gnu++11 option. +	* testsuite/30_threads/thread/swap/1.cc: Include <utility> +	instead of <bits/move.h>. + +2025-10-29  Tomasz Kamiński  <tkaminsk@redhat.com> + +	PR libstdc++/119721 +	* include/std/tuple (tuple<>::operator=(const _Tuple&) const) +	[__cpp_lib_ranges_zip]: Define. +	* testsuite/23_containers/tuple/cons/119721.cc: Test const +	assignment. + +2025-10-29  Osama Abdelkader  <osama.abdelkader@gmail.com> +	    Tomasz Kamiński  <tkaminsk@redhat.com> + +	PR libstdc++/119721 +	* include/std/tuple (tuple<>::tuple(const tuple&)) +	(tuple<>::operator=(const tuple&)): Define as defaulted. +	(tuple<>::swap): Moved the defintion after assignments. +	(tuple<>::tuple(_UTuple&&)) +	(tuple<>::tuple(allocator_arg_t, const _Alloc&, _UTuple&&)) +	(tuple<>::operator=(_UTuple&&)) [__cpp_lib_tuple_like]: Define. +	(tuple<>::operator==, tuple<>::opeator<=>): Parenthesize +	constrains individually. +	* testsuite/23_containers/tuple/cons/119721.cc: New test for +	constructors and assignments with empty tuple-like types. +	* testsuite/20_util/tuple/requirements/empty_trivial.cc: +	New test verifying tuple<> remains trivially copyable. + +2025-10-29  Jonathan Wakely  <jwakely@redhat.com> + +	* include/bits/regex.tcc (regex_traits::value): Implement +	without using istringstream. +	* include/std/regex: Do not include <sstream>. + +2025-10-28  Jonathan Wakely  <jwakely@redhat.com> + +	PR libstdc++/122401 +	* testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc: +	Do not try to acquire locks on the thread that already holds a +	lock. Add -pthread for et pthread. +  2025-10-27  Jonathan Wakely  <jwakely@redhat.com>  	PR libstdc++/122401 diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc index b94fe44..48917cd 100644 --- a/libstdc++-v3/include/bits/regex.tcc +++ b/libstdc++-v3/include/bits/regex.tcc @@ -331,20 +331,53 @@ namespace __detail  	    && __c == __fctyp.widen('_'));      } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr    template<typename _Ch_type>      int      regex_traits<_Ch_type>::      value(_Ch_type __ch, int __radix) const      { -      std::basic_istringstream<char_type> __is(string_type(1, __ch)); -      long __v; -      if (__radix == 8) -	__is >> std::oct; -      else if (__radix == 16) -	__is >> std::hex; -      __is >> __v; -      return __is.fail() ? -1 : __v; +      if constexpr (sizeof(_Ch_type) > 1) +	{ +	  const auto& __ctyp = std::use_facet<ctype<_Ch_type>>(_M_locale); +	  const char __c = __ctyp.narrow(__ch, '\0'); +	  return regex_traits<char>{}.value(__c, __radix); +	} +      else +	{ +	  const char __c = static_cast<char>(__ch); +	  const char __max_digit = __radix == 8 ? '7' : '9'; +	  if ('0' <= __c && __c <= __max_digit) +	    return __c - '0'; +	  if (__radix < 16) +	    return -1; +	  switch (__c) +	  { +	    case 'a': +	    case 'A': +	      return 10; +	    case 'b': +	    case 'B': +	      return 11; +	    case 'c': +	    case 'C': +	      return 12; +	    case 'd': +	    case 'D': +	      return 13; +	    case 'e': +	    case 'E': +	      return 14; +	    case 'f': +	    case 'F': +	      return 15; +	    default: +	      return -1; +	    } +	}      } +#pragma GCC diagnostic pop    template<typename _Bi_iter, typename _Alloc>    template<typename _Out_iter> diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 1bf98f7..29ecf15 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -2191,6 +2191,15 @@ ftms = {    };  }; +ftms = { +  name = is_implicit_lifetime; +  values = { +    v =  202302; +    cxxmin = 23; +    extra_cond = "__has_builtin(__builtin_is_implicit_lifetime)"; +  }; +}; +  // Standard test specifications.  stds[97] = ">= 199711L";  stds[03] = ">= 199711L"; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 66de8b4..5901d27 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -2455,4 +2455,14 @@  #endif /* !defined(__cpp_lib_philox_engine) */  #undef __glibcxx_want_philox_engine +#if !defined(__cpp_lib_is_implicit_lifetime) +# if (__cplusplus >= 202100L) && (__has_builtin(__builtin_is_implicit_lifetime)) +#  define __glibcxx_is_implicit_lifetime 202302L +#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_implicit_lifetime) +#   define __cpp_lib_is_implicit_lifetime 202302L +#  endif +# endif +#endif /* !defined(__cpp_lib_is_implicit_lifetime) */ +#undef __glibcxx_want_is_implicit_lifetime +  #undef __glibcxx_want_all diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex index 0223066..9121d26 100644 --- a/libstdc++-v3/include/std/regex +++ b/libstdc++-v3/include/std/regex @@ -41,7 +41,6 @@  #include <bitset>  #include <locale> -#include <sstream>  #include <stack>  #include <stdexcept>  #include <string> diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index c064a92..d4db125 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -1984,14 +1984,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION      class tuple<>      {      public: +      // We need the default since we're going to define no-op +      // allocator constructors. +      tuple() = default; +      // Defaulted copy operations to maintain trivial copyability. +      // and support non-const assignment expressions. +      tuple(const tuple&) = default; +      tuple& operator=(const tuple&) = default; +        _GLIBCXX20_CONSTEXPR        void swap(tuple&) noexcept { /* no-op */ } +  #if __cpp_lib_ranges_zip // >= C++23 -      constexpr void swap(const tuple&) const noexcept { /* no-op */ } +      template<same_as<tuple> _Tuple = tuple> +      constexpr const tuple& +      operator=(const _Tuple&) const noexcept +      { return *this; } + +      constexpr void swap(const tuple&) const noexcept +      { /* no-op */ }  #endif -      // We need the default since we're going to define no-op -      // allocator constructors. -      tuple() = default; +        // No-op allocator constructors.        template<typename _Alloc>  	_GLIBCXX20_CONSTEXPR @@ -2001,16 +2014,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION  	tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }  #if __cpp_lib_tuple_like // >= C++23 -      // Comparison operators for tuple<> with other empty tuple-like types        template<__tuple_like _UTuple> -	requires (!__is_tuple_v<_UTuple> && tuple_size_v<_UTuple> == 0) +	requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>) +		  && (!is_same_v<remove_cvref_t<_UTuple>, allocator_arg_t>) +		  && (tuple_size_v<remove_cvref_t<_UTuple>> == 0) +      constexpr +      tuple(_UTuple&&) noexcept { } + +      template<typename _Alloc, __tuple_like _UTuple> +	requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>) +		  && (tuple_size_v<remove_cvref_t<_UTuple>> == 0) +      constexpr +      tuple(allocator_arg_t, const _Alloc&, _UTuple&&) noexcept { } + +      template<__tuple_like _UTuple> +	requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>) +		  && (tuple_size_v<remove_cvref_t<_UTuple>> == 0) +      constexpr tuple& +      operator=(_UTuple&&) noexcept +      { return *this; } + +      template<__tuple_like _UTuple> +	requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>) +		  && (tuple_size_v<remove_cvref_t<_UTuple>> == 0) +      constexpr const tuple& +      operator=(_UTuple&&) const noexcept +      { return *this; } + +      template<__tuple_like _UTuple> +	requires (!__is_tuple_v<_UTuple>) && (tuple_size_v<_UTuple> == 0)        [[nodiscard]]        friend constexpr bool        operator==(const tuple&, const _UTuple&) noexcept        { return true; }        template<__tuple_like _UTuple> -	requires (!__is_tuple_v<_UTuple> && tuple_size_v<_UTuple> == 0) +	requires (!__is_tuple_v<_UTuple>) && (tuple_size_v<_UTuple> == 0)        friend constexpr strong_ordering        operator<=>(const tuple&, const _UTuple&) noexcept        { return strong_ordering::equal; } diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 77ebb7e..d28b0773 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -47,6 +47,7 @@  #define __glibcxx_want_is_aggregate  #define __glibcxx_want_is_constant_evaluated  #define __glibcxx_want_is_final +#define __glibcxx_want_is_implicit_lifetime  #define __glibcxx_want_is_invocable  #define __glibcxx_want_is_layout_compatible  #define __glibcxx_want_is_nothrow_convertible @@ -4053,6 +4054,22 @@ template<typename _Ret, typename _Fn, typename... _Args>  # endif  #endif +#ifdef __cpp_lib_is_implicit_lifetime // C++ >= 23 +  /// True if the type is an implicit-lifetime type. +  /// @since C++23 + +  template<typename _Tp> +    struct is_implicit_lifetime +    : bool_constant<__builtin_is_implicit_lifetime(_Tp)> +    { }; + +  /// @ingroup variable_templates +  /// @since C++23 +  template<typename _Tp> +    inline constexpr bool is_implicit_lifetime_v +      = __builtin_is_implicit_lifetime(_Tp); +#endif +  #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp    /// True if _Tp is a reference type, a _Up value can be bound to _Tp in    /// direct-initialization, and a temporary object would be bound to diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in index 4c11b1b..28f0e8c 100644 --- a/libstdc++-v3/src/c++23/std.cc.in +++ b/libstdc++-v3/src/c++23/std.cc.in @@ -3230,6 +3230,10 @@ export namespace std    using std::is_scoped_enum;    using std::is_scoped_enum_v;  #endif +#if __cpp_lib_is_implicit_lifetime +  using std::is_implicit_lifetime; +  using std::is_implicit_lifetime_v; +#endif  }  // <typeindex> diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc index cd576ca..350a548 100644 --- a/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc +++ b/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc @@ -1,5 +1,5 @@  // { dg-do compile } -// { dg-options "-std=gnu++11" } +// { dg-add-options no_pch }  // Copyright (C) 2009-2025 Free Software Foundation, Inc.  // @@ -19,4 +19,4 @@  // <http://www.gnu.org/licenses/>.  // libstdc++/42319 -#include <bits/char_traits.h> +#include <ios> diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc new file mode 100644 index 0000000..d8cb181 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc @@ -0,0 +1,129 @@ +// Copyright (C) 2025 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 compile { target c++23 } } +// { dg-add-options no_pch } + +#include <type_traits> + +#ifndef __cpp_lib_is_implicit_lifetime +# error "Feature test macro for is_implicit_lifetime is missing in <type_traits>" +#elif __cpp_lib_is_implicit_lifetime < 202302L +# error "Feature test macro for is_implicit_lifetime has wrong value in <type_traits>" +#endif + +#include <testsuite_tr1.h> + +template<typename T> +  concept Is_implicit_lifetime +    = __gnu_test::test_category<std::is_implicit_lifetime, T>(true); + +static_assert( ! Is_implicit_lifetime<void> ); +static_assert( ! Is_implicit_lifetime<const void> ); +static_assert( ! Is_implicit_lifetime<volatile void> ); +static_assert( Is_implicit_lifetime<char> ); +static_assert( Is_implicit_lifetime<signed char> ); +static_assert( Is_implicit_lifetime<const unsigned char> ); +static_assert( Is_implicit_lifetime<short> ); +static_assert( Is_implicit_lifetime<volatile unsigned short> ); +static_assert( Is_implicit_lifetime<int> ); +static_assert( Is_implicit_lifetime<unsigned int> ); +static_assert( Is_implicit_lifetime<const volatile long> ); +static_assert( Is_implicit_lifetime<unsigned long> ); +static_assert( Is_implicit_lifetime<long long> ); +static_assert( Is_implicit_lifetime<unsigned long long> ); +static_assert( Is_implicit_lifetime<float> ); +static_assert( Is_implicit_lifetime<double> ); +static_assert( Is_implicit_lifetime<long double volatile> ); +enum W { W1 }; +static_assert( Is_implicit_lifetime<W> ); +enum class X : int { X1 }; +static_assert( Is_implicit_lifetime<const volatile X> ); +static_assert( Is_implicit_lifetime<int *> ); +static_assert( Is_implicit_lifetime<int (*) (int)> ); +struct Y { int g; int foo (int); }; +static_assert( Is_implicit_lifetime<int (Y::*)> ); +static_assert( Is_implicit_lifetime<int (Y::*) (int)> ); +static_assert( ! Is_implicit_lifetime<int &> ); +static_assert( ! Is_implicit_lifetime<char &&> ); +static_assert( Is_implicit_lifetime<int []> ); +static_assert( Is_implicit_lifetime<int [1]> ); +static_assert( Is_implicit_lifetime<const Y [42]> ); +static_assert( ! Is_implicit_lifetime<int ()> ); +static_assert( ! Is_implicit_lifetime<int () &> ); +static_assert( ! Is_implicit_lifetime<int () const> ); +static_assert( ! Is_implicit_lifetime<int (&) ()> ); +struct Z; +static_assert( Is_implicit_lifetime<Z []> ); +static_assert( Is_implicit_lifetime<Z [5]> ); +struct A { int a, b, c; }; +static_assert( Is_implicit_lifetime<A> ); +class B { static int a; private: static int b; public: int c; }; +static_assert( Is_implicit_lifetime<B> ); +struct C { C () {} int a, b, c; }; +static_assert( Is_implicit_lifetime<C> ); +struct D { explicit D (int) {} int a, b, c; }; +static_assert( Is_implicit_lifetime<D> ); +struct E : public A { int d, e, f; }; +static_assert( Is_implicit_lifetime<E> ); +struct F : public C { using C::C; int d, e, f; }; +static_assert( Is_implicit_lifetime<F> ); +class G { int a, b; }; +static_assert( Is_implicit_lifetime<G> ); +struct H { private: int a, b; }; +static_assert( Is_implicit_lifetime<H> ); +struct I { protected: int a, b; }; +static_assert( Is_implicit_lifetime<I> ); +struct J { int a, b; void foo (); }; +static_assert( Is_implicit_lifetime<J> ); +struct K { int a, b; virtual void foo (); }; +static_assert( ! Is_implicit_lifetime<K> ); +struct L : virtual public A { int d, e; }; +static_assert( ! Is_implicit_lifetime<L> ); +struct M : protected A { int d, e; }; +static_assert( Is_implicit_lifetime<M> ); +struct N : private A { int d, e; }; +static_assert( Is_implicit_lifetime<N> ); +struct O { O () = delete; int a, b, c; }; +static_assert( Is_implicit_lifetime<O> ); +struct P { P () = default; int a, b, c; }; +static_assert( Is_implicit_lifetime<P> ); +struct Q { Q (); Q (const Q &); int a, b, c; }; +static_assert( ! Is_implicit_lifetime<Q> ); +struct R { R (); R (const R &); R (R &&) = default; int a, b, c; }; +static_assert( Is_implicit_lifetime<R> ); +struct S { S (); ~S (); int a, b, c; }; +static_assert( ! Is_implicit_lifetime<S> ); +static_assert( Is_implicit_lifetime<S [3]> ); +struct T { T (); ~T () = default; int a, b, c; }; +static_assert( Is_implicit_lifetime<T> ); +struct U { U (); U (const U &) = default; int a, b, c; }; +static_assert( Is_implicit_lifetime<U> ); +struct V { V () = default; V (const V &); int a, b, c; }; +static_assert( Is_implicit_lifetime<V> ); +struct AA { Q a; Q b; }; +static_assert( Is_implicit_lifetime<AA> ); +struct AB { Q a; Q b; ~AB () = default; }; +static_assert( Is_implicit_lifetime<AB> ); +struct AC { Q a; Q b; ~AC () {} }; +static_assert( ! Is_implicit_lifetime<AC> ); +struct AD : public Q {}; +static_assert( Is_implicit_lifetime<AD> ); +struct AE : public Q { ~AE () = default; }; +static_assert( Is_implicit_lifetime<AE> ); +struct AF : public Q { ~AF () {} }; +static_assert( ! Is_implicit_lifetime<AF> ); diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc new file mode 100644 index 0000000..ed90b47 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc @@ -0,0 +1,27 @@ +// Copyright (C) 2025 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 compile { target c++23 } } +// { dg-add-options no_pch } + +#include <version> + +#ifndef __cpp_lib_is_implicit_lifetime +# error "Feature test macro for is_implicit_lifetime is missing in <version>" +#elif __cpp_lib_is_implicit_lifetime < 202302L +# error "Feature test macro for is_implicit_lifetime has wrong value in <version>" +#endif diff --git a/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc b/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc new file mode 100644 index 0000000..ee18bb3 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc @@ -0,0 +1,17 @@ +// { dg-do compile { target c++11 } } + +#include <tuple> +#include <type_traits> + +// Check that tuple<> has the expected trivial properties +static_assert(std::is_trivially_copyable<std::tuple<>>::value, +	      "tuple<> should be trivially copyable"); +static_assert(std::is_trivially_copy_constructible<std::tuple<>>::value, +	      "tuple<> should be trivially copy constructible"); +static_assert(std::is_trivially_move_constructible<std::tuple<>>::value, +	      "tuple<> should be trivially move constructible"); +static_assert(std::is_trivially_copy_assignable<std::tuple<>>::value, +	      "tuple<> should be trivially copy assignable"); +static_assert(std::is_trivially_move_assignable<std::tuple<>>::value, +	      "tuple<> should be trivially move assignable"); + diff --git a/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc new file mode 100644 index 0000000..1d15238 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc @@ -0,0 +1,121 @@ +// { dg-do run { target c++23 } } + +// Test for PR libstdc++/119721: tuple<> construction/assignment with array<T, 0> + +#include <tuple> +#include <array> +#include <memory> +#include <testsuite_hooks.h> + +constexpr void +test01() +{ +  std::array<int, 0> a{}; +   +  // Constructor from array<int, 0> +  std::tuple<> t1(a); +  std::tuple<> t2(std::move(a)); +   +  // Assignment from array<int, 0> +  std::tuple<> t3; +  t3 = a; +  t3 = std::move(a); +   +  VERIFY( t1 == a ); +  VERIFY( t2 == a ); +  VERIFY( t3 == a ); +} + +constexpr void +test02() +{ +  // Test with non-comparable element type +  struct NonComparable +  { +    void operator==(const NonComparable&) const = delete; +    void operator<=>(const NonComparable&) const = delete; +  }; +   +  std::array<NonComparable, 0> a{}; +   +  std::tuple<> t1(a); +  std::tuple<> t2(std::move(a)); +   +  std::tuple<> t3; +  t3 = a; +  t3 = std::move(a); +   +  VERIFY( t1 == a ); +} + +constexpr void +test03() +{ +  // Test assignment return type (non-const assignment) +  std::tuple<> t, u; +  std::tuple<>& r1 = (t = u); +  VERIFY( &r1 == &t ); +   +  std::tuple<>& r2 = (t = {}); +  VERIFY( &r2 == &t ); +   +  std::array<int, 0> a{}; +  std::tuple<>& r3 = (t = a); +  VERIFY( &r3 == &t ); +} + +constexpr void +test04() +{ +  std::array<int, 0> a{}; +  const std::tuple<> t1; + +  // Const assignment from array +  std::tuple<> t2; +  const std::tuple<>& r1 = (t1 = t2); +  VERIFY( &r1 == &t1 ); +  const std::tuple<>& r2 = (t1 = std::move(t2)); +  VERIFY( &r2 == &t1 ); + +  const std::tuple<>& r3 = (t1 = {}); +  VERIFY( &r3 == &t1 ); + +  // Const assignment from array +  const std::tuple<>& r4 = (t1 = a); +  VERIFY( &r4 == &t1 ); +  const std::tuple<>& r5 = (t1 = std::move(a)); +  VERIFY( &r5 == &t1 ); +} + +void +test05() +{ +  std::array<int, 0> a{}; +  std::allocator<int> alloc; +   +  // Allocator constructor from array +  std::tuple<> t1(std::allocator_arg, alloc, a); +  std::tuple<> t2(std::allocator_arg, alloc, std::move(a)); +   +  VERIFY( t1 == a ); +  VERIFY( t2 == a ); +} + +int main() +{ +  auto test_all = [] { +    test01(); +    test02(); +    test03(); +    test04(); +    return true; +  }; + +  test_all(); +  static_assert( test_all() ); +   +  // allocator test is not constexpr +  test05();  +  return 0; +} + diff --git a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc index cebbb3a..5736b7d 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc @@ -1,4 +1,7 @@  // { dg-do run { target c++14 } } +// { dg-additional-options "-pthread" { target pthread } } +// { dg-require-gthreads "" } +// { dg-require-effective-target hosted }  #include <shared_mutex>  #include <chrono> @@ -8,10 +11,18 @@  namespace chrono = std::chrono; -// thread.timedmutex.requirements.general: +// [thread.timedmutex.requirements.general]:  //   If abs_time has already passed, the function attempts to obtain  //   ownership without blocking (as if by calling try_lock()). +// C++14 [thread.sharedtimedmutex.class] 3.2 says it's undefined for a thread +// to attempt to recursively gain any ownership of a shared_timed_mutex. +// This isn't just theoretical, as Glibc's pthread_rwlock_timedrdlock will +// return EDEADLK if called on the same thread that already holds the +// exclusive (write) lock. +#define VERIFY_IN_NEW_THREAD(X) \ +  (void) std::async(std::launch::async, [&] { VERIFY(X); }) +  template <typename Clock>  void  test_exclusive_absolute(chrono::nanoseconds offset) @@ -19,7 +30,7 @@ test_exclusive_absolute(chrono::nanoseconds offset)    std::shared_timed_mutex stm;    chrono::time_point<Clock> tp(offset);    VERIFY(stm.try_lock_until(tp)); -  VERIFY(!stm.try_lock_until(tp)); +  VERIFY_IN_NEW_THREAD(!stm.try_lock_until(tp));  }  template <typename Clock> @@ -32,15 +43,7 @@ test_shared_absolute(chrono::nanoseconds offset)    stm.unlock_shared();    VERIFY(stm.try_lock_for(chrono::seconds{10})); - -  { -    // NPTL will give us EDEADLK if pthread_rwlock_timedrdlock() is called on -    // the same thread that already holds the exclusive (write) lock, so let's -    // arrange for a different thread to try to acquire the shared lock. -    auto t = std::async(std::launch::async, [&stm, tp]() { -	VERIFY(!stm.try_lock_shared_until(tp)); -      }); -  } +  VERIFY_IN_NEW_THREAD(!stm.try_lock_shared_until(tp));  }  // The type of clock used for the actual wait depends on whether @@ -53,7 +56,7 @@ test_exclusive_relative(chrono::nanoseconds offset)    std::shared_timed_mutex stm;    const auto d = -Clock::now().time_since_epoch() + offset;    VERIFY(stm.try_lock_for(d)); -  VERIFY(!stm.try_lock_for(d)); +  VERIFY_IN_NEW_THREAD(!stm.try_lock_for(d));  }  template <typename Clock> @@ -66,7 +69,7 @@ test_shared_relative(chrono::nanoseconds offset)    stm.unlock_shared();    // Should complete immediately    VERIFY(stm.try_lock_for(chrono::seconds{10})); -  VERIFY(!stm.try_lock_shared_for(d)); +  VERIFY_IN_NEW_THREAD(!stm.try_lock_shared_for(d));  }  int main() diff --git a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc index 9616b15..b1fde09 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc @@ -23,7 +23,7 @@  #include <thread>  #include <system_error> -#include <bits/move.h> // std::move +#include <utility> // std::move  #include <testsuite_hooks.h>  void f() { } | 
