diff options
author | Martin Liska <mliska@suse.cz> | 2022-09-12 10:43:19 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-09-12 10:43:19 +0200 |
commit | fdb97cd0b7d15efa39ba79dca44be93debb0ef12 (patch) | |
tree | 65a6d95503fb9897bda29c72a629e57bb773d1c1 /libstdc++-v3 | |
parent | 918bc838c2803f08e4d7ccd179396d48cb8ec804 (diff) | |
parent | 643ae816f17745a77b62188b6bf169211609a59b (diff) | |
download | gcc-fdb97cd0b7d15efa39ba79dca44be93debb0ef12.zip gcc-fdb97cd0b7d15efa39ba79dca44be93debb0ef12.tar.gz gcc-fdb97cd0b7d15efa39ba79dca44be93debb0ef12.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'libstdc++-v3')
24 files changed, 562 insertions, 122 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c9a7f35..2e15013 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,120 @@ +2022-09-09 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/atomic_base.h (__atomic_impl::__compare_exchange): + Rename __weak to __is_weak. + * testsuite/17_intro/names.cc: Add __weak and __strong. + +2022-09-09 Patrick Palka <ppalka@redhat.com> + + PR libstdc++/106803 + * include/std/ranges (views::_ZipTransform::operator()): Correct + return type in the empty case. + (views::_AdjacentTransform::operator()): Likewise. + +2022-09-09 Patrick Palka <ppalka@redhat.com> + + PR libstdc++/106798 + * include/std/ranges (adjacent_view::_Iterator::_Iterator): Fix + typo. + * testsuite/std/ranges/adaptors/adjacent/1.cc (test04): New test. + +2022-09-09 Patrick Palka <ppalka@redhat.com> + + PR libstdc++/106766 + * include/std/ranges (zip_view::_Iterator::operator-): Use + __to_unsigned_like instead of make_unsigned_t. + (zip_view::_Sentinel::operator-): Likewise. + * testsuite/std/ranges/zip/1.cc (test04): New test. + +2022-09-08 François Dumont <fdumont@gcc.gnu.org> + + * testsuite/util/testsuite_performance.h (__gnu_test::MallocInfo): New. + (__gnu_test::malloc_info): New, replace mallinfo on current platform + supporting it and use mallinfo2 when glibc >= 2.33. + +2022-09-08 Jonathan Wakely <jwakely@redhat.com> + + PR c++/106838 + * testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: + Prune additional errors from front-end. + * testsuite/20_util/is_move_constructible/incomplete_neg.cc: + Likewise. + * testsuite/20_util/is_nothrow_swappable/incomplete_neg.cc: + Likewise. + * testsuite/20_util/is_nothrow_swappable_with/incomplete_neg.cc: + Likewise. + * testsuite/20_util/is_swappable_with/incomplete_neg.cc: + Likewise. + +2022-09-08 Jonathan Wakely <jwakely@redhat.com> + + * include/c_global/cstddef (byte): Add always_inline attribute + to all operator overloads. + (to_integer): Add always_inline attribute. + +2022-09-08 Thomas Rodgers <trodgers@redhat.com> + Jakub Jelinek <jakub@redhat.com> + Jonathan Wakely <jwakely@redhat.com> + + * include/bits/atomic_base.h (__atomic_impl::__maybe_has_padding): + New function. + (__atomic_impl::clear_padding): Likewise. + (__atomic_impl::__compare_exchange): Likewise. + (__atomic_impl::compare_exchange_weak): Delegate to + __compare_exchange. + (__atomic_impl::compare_exchange_strong): Likewise. + * include/std/atomic (atomic<T>::atomic(T)): Clear padding when + possible in a constexpr function. + (atomic::store): Clear padding. + (atomic::exchange): Likewise. + (atomic::compare_exchange_weak): Use __compare_exchange. + (atomic::compare_exchange_strong): Likewise. + * testsuite/29_atomics/atomic/compare_exchange_padding.cc: New + test. + * testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc: + New test. + +2022-09-08 Jonathan Wakely <jwakely@redhat.com> + + * include/std/system_error (__adl_only::make_error_code): Add + deleted function. + (__adl_only::make_error_condition): Likewise. + (error_code::error_code(ErrorCodeEnum)): Add using-declaration + for deleted function. + (error_condition::error_condition(ErrorConditionEnum)): + Likewise. + * testsuite/19_diagnostics/error_code/cons/lwg3629.cc: New test. + * testsuite/19_diagnostics/error_condition/cons/lwg3629.cc: New test. + +2022-09-07 Jonathan Wakely <jwakely@redhat.com> + + * include/std/barrier: Add missing runtime exception. + +2022-09-07 Patrick Palka <ppalka@redhat.com> + + * include/std/type_traits (is_reference): Make the primary + template derive from false_type. Define two partial + specializations that derive from true_type. + +2022-09-07 Patrick Palka <ppalka@redhat.com> + + * include/std/type_traits (__is_void_helper): Remove. + (is_void): Make the primary template derive from false_type, + and define four explicit specializations that derive from + true_type. + (__is_null_pointer_helper, is_null_pointer): Likewise. + +2022-09-07 Jason Merrill <jason@redhat.com> + + * libsupc++/dyncast.cc (__dynamic_cast): Avoid virtual function + call in simple success case. + +2022-09-06 Philipp Fent <fent@in.tum.de> + + * testsuite/libstdc++-prettyprinters/48362.cc: Fix expected + tuple indices. + * testsuite/libstdc++-prettyprinters/cxx11.cc: Likewise. + 2022-09-05 Jonathan Wakely <jwakely@redhat.com> * include/std/type_traits (__success_type, __failure_type): Move diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index d29e443..6ea3268 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -33,6 +33,7 @@ #pragma GCC system_header #include <bits/c++config.h> +#include <new> // For placement new #include <stdint.h> #include <bits/atomic_lockfree_defines.h> #include <bits/move.h> @@ -952,19 +953,77 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), int(__m)); } }; - /// @endcond - -#if __cplusplus > 201703L - /// @cond undocumented - - // Implementation details of atomic_ref and atomic<floating-point>. namespace __atomic_impl { + // Implementation details of atomic padding handling + + template<typename _Tp> + constexpr bool + __maybe_has_padding() + { +#if ! __has_builtin(__builtin_clear_padding) + return false; +#elif __has_builtin(__has_unique_object_representations) + return !__has_unique_object_representations(_Tp) + && !is_same<_Tp, float>::value && !is_same<_Tp, double>::value; +#else + return true; +#endif + } + + template<typename _Tp> + _GLIBCXX_ALWAYS_INLINE _Tp* + __clear_padding(_Tp& __val) noexcept + { + auto* __ptr = std::__addressof(__val); +#if __has_builtin(__builtin_clear_padding) + if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Tp>()) + __builtin_clear_padding(__ptr); +#endif + return __ptr; + } + // Remove volatile and create a non-deduced context for value arguments. template<typename _Tp> - using _Val = remove_volatile_t<_Tp>; + using _Val = typename remove_volatile<_Tp>::type; + + template<typename _Tp> + _GLIBCXX_ALWAYS_INLINE bool + __compare_exchange(_Tp& __val, _Val<_Tp>& __e, _Val<_Tp>& __i, + bool __is_weak, + memory_order __s, memory_order __f) noexcept + { + __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); + + using _Vp = _Val<_Tp>; + + if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Vp>()) + { + // We must not modify __e on success, so cannot clear its padding. + // Copy into a buffer and clear that, then copy back on failure. + alignas(_Vp) unsigned char __buf[sizeof(_Vp)]; + _Vp* __exp = ::new((void*)__buf) _Vp(__e); + __atomic_impl::__clear_padding(*__exp); + if (__atomic_compare_exchange(std::__addressof(__val), __exp, + __atomic_impl::__clear_padding(__i), + __is_weak, int(__s), int(__f))) + return true; + __builtin_memcpy(std::__addressof(__e), __exp, sizeof(_Vp)); + return false; + } + else + return __atomic_compare_exchange(std::__addressof(__val), + std::__addressof(__e), + std::__addressof(__i), + __is_weak, int(__s), int(__f)); + } + } // namespace __atomic_impl - // As above, but for difference_type arguments. +#if __cplusplus > 201703L + // Implementation details of atomic_ref and atomic<floating-point>. + namespace __atomic_impl + { + // Like _Val<T> above, but for difference_type arguments. template<typename _Tp> using _Diff = __conditional_t<is_pointer_v<_Tp>, ptrdiff_t, _Val<_Tp>>; @@ -979,7 +1038,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> _GLIBCXX_ALWAYS_INLINE void store(_Tp* __ptr, _Val<_Tp> __t, memory_order __m) noexcept - { __atomic_store(__ptr, std::__addressof(__t), int(__m)); } + { + __atomic_store(__ptr, __atomic_impl::__clear_padding(__t), int(__m)); + } template<typename _Tp> _GLIBCXX_ALWAYS_INLINE _Val<_Tp> @@ -997,7 +1058,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; auto* __dest = reinterpret_cast<_Val<_Tp>*>(__buf); - __atomic_exchange(__ptr, std::__addressof(__desired), __dest, int(__m)); + __atomic_exchange(__ptr, __atomic_impl::__clear_padding(__desired), + __dest, int(__m)); return *__dest; } @@ -1007,11 +1069,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Val<_Tp> __desired, memory_order __success, memory_order __failure) noexcept { - __glibcxx_assert(__is_valid_cmpexch_failure_order(__failure)); - - return __atomic_compare_exchange(__ptr, std::__addressof(__expected), - std::__addressof(__desired), true, - int(__success), int(__failure)); + return __atomic_impl::__compare_exchange(*__ptr, __expected, __desired, + true, __success, __failure); } template<typename _Tp> @@ -1020,11 +1079,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Val<_Tp> __desired, memory_order __success, memory_order __failure) noexcept { - __glibcxx_assert(__is_valid_cmpexch_failure_order(__failure)); - - return __atomic_compare_exchange(__ptr, std::__addressof(__expected), - std::__addressof(__desired), false, - int(__success), int(__failure)); + return __atomic_impl::__compare_exchange(*__ptr, __expected, __desired, + false, __success, __failure); } #if __cpp_lib_atomic_wait @@ -1955,9 +2011,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tp** _M_ptr; }; +#endif // C++2a /// @endcond -#endif // C++2a /// @} group atomics diff --git a/libstdc++-v3/include/c_global/cstddef b/libstdc++-v3/include/c_global/cstddef index 4970c2d..df2d88a 100644 --- a/libstdc++-v3/include/c_global/cstddef +++ b/libstdc++-v3/include/c_global/cstddef @@ -119,55 +119,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __byte_op_t = typename __byte_operand<_IntegerType>::__type; template<typename _IntegerType> + [[__gnu__::__always_inline__]] constexpr __byte_op_t<_IntegerType> operator<<(byte __b, _IntegerType __shift) noexcept { return (byte)(unsigned char)((unsigned)__b << __shift); } template<typename _IntegerType> + [[__gnu__::__always_inline__]] constexpr __byte_op_t<_IntegerType> operator>>(byte __b, _IntegerType __shift) noexcept { return (byte)(unsigned char)((unsigned)__b >> __shift); } + [[__gnu__::__always_inline__]] constexpr byte operator|(byte __l, byte __r) noexcept { return (byte)(unsigned char)((unsigned)__l | (unsigned)__r); } + [[__gnu__::__always_inline__]] constexpr byte operator&(byte __l, byte __r) noexcept { return (byte)(unsigned char)((unsigned)__l & (unsigned)__r); } + [[__gnu__::__always_inline__]] constexpr byte operator^(byte __l, byte __r) noexcept { return (byte)(unsigned char)((unsigned)__l ^ (unsigned)__r); } + [[__gnu__::__always_inline__]] constexpr byte operator~(byte __b) noexcept { return (byte)(unsigned char)~(unsigned)__b; } template<typename _IntegerType> + [[__gnu__::__always_inline__]] constexpr __byte_op_t<_IntegerType>& operator<<=(byte& __b, _IntegerType __shift) noexcept { return __b = __b << __shift; } template<typename _IntegerType> + [[__gnu__::__always_inline__]] constexpr __byte_op_t<_IntegerType>& operator>>=(byte& __b, _IntegerType __shift) noexcept { return __b = __b >> __shift; } + [[__gnu__::__always_inline__]] constexpr byte& operator|=(byte& __l, byte __r) noexcept { return __l = __l | __r; } + [[__gnu__::__always_inline__]] constexpr byte& operator&=(byte& __l, byte __r) noexcept { return __l = __l & __r; } + [[__gnu__::__always_inline__]] constexpr byte& operator^=(byte& __l, byte __r) noexcept { return __l = __l ^ __r; } template<typename _IntegerType> - [[nodiscard]] + [[nodiscard,__gnu__::__always_inline__]] constexpr _IntegerType to_integer(__byte_op_t<_IntegerType> __b) noexcept { return _IntegerType(__b); } diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic index 70055b8..b913960 100644 --- a/libstdc++-v3/include/std/atomic +++ b/libstdc++-v3/include/std/atomic @@ -230,7 +230,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; - constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } + constexpr atomic(_Tp __i) noexcept : _M_i(__i) + { +#if __cplusplus >= 201402L && __has_builtin(__builtin_clear_padding) + if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Tp>()) + __builtin_clear_padding(std::__addressof(_M_i)); +#endif + } operator _Tp() const noexcept { return load(); } @@ -270,13 +276,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { - __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m)); + __atomic_store(std::__addressof(_M_i), + __atomic_impl::__clear_padding(__i), + int(__m)); } void store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { - __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m)); + __atomic_store(std::__addressof(_M_i), + __atomic_impl::__clear_padding(__i), + int(__m)); } _Tp @@ -302,7 +312,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); - __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), + __atomic_exchange(std::__addressof(_M_i), + __atomic_impl::__clear_padding(__i), __ptr, int(__m)); return *__ptr; } @@ -313,7 +324,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); - __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), + __atomic_exchange(std::__addressof(_M_i), + __atomic_impl::__clear_padding(__i), __ptr, int(__m)); return *__ptr; } @@ -322,24 +334,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { - __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); - - return __atomic_compare_exchange(std::__addressof(_M_i), - std::__addressof(__e), - std::__addressof(__i), - true, int(__s), int(__f)); + return __atomic_impl::__compare_exchange(_M_i, __e, __i, true, + __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { - __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); - - return __atomic_compare_exchange(std::__addressof(_M_i), - std::__addressof(__e), - std::__addressof(__i), - true, int(__s), int(__f)); + return __atomic_impl::__compare_exchange(_M_i, __e, __i, true, + __s, __f); } bool @@ -358,24 +362,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { - __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); - - return __atomic_compare_exchange(std::__addressof(_M_i), - std::__addressof(__e), - std::__addressof(__i), - false, int(__s), int(__f)); + return __atomic_impl::__compare_exchange(_M_i, __e, __i, false, + __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { - __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); - - return __atomic_compare_exchange(std::__addressof(_M_i), - std::__addressof(__e), - std::__addressof(__i), - false, int(__s), int(__f)); + return __atomic_impl::__compare_exchange(_M_i, __e, __i, false, + __s, __f); } bool @@ -390,7 +386,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return compare_exchange_strong(__e, __i, __m, __cmpexch_failure_order(__m)); } -#if __cpp_lib_atomic_wait +#if __cpp_lib_atomic_wait void wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept { @@ -407,7 +403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void notify_all() noexcept { std::__atomic_notify_address(&_M_i, true); } -#endif // __cpp_lib_atomic_wait +#endif // __cpp_lib_atomic_wait }; #undef _GLIBCXX20_INIT diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier index 2a26505..997e0a8 100644 --- a/libstdc++-v3/include/std/barrier +++ b/libstdc++-v3/include/std/barrier @@ -13,8 +13,13 @@ // 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 +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. // This implementation is based on libcxx/include/barrier diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 2b5cb05..20eb4e8 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -4657,8 +4657,8 @@ namespace views::__adaptor return ranges::min({difference_type(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_current))...}, ranges::less{}, - [](difference_type __i) -> make_unsigned_t<difference_type> { - return __i < 0 ? -__i : __i; + [](difference_type __i) { + return __detail::__to_unsigned_like(__i < 0 ? -__i : __i); }); }(make_index_sequence<sizeof...(_Vs)>{}); } @@ -4726,8 +4726,8 @@ namespace views::__adaptor return [&]<size_t... _Is>(index_sequence<_Is...>) { return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...}, ranges::less{}, - [](_Ret __i) -> make_unsigned_t<_Ret> { - return __i < 0 ? -__i : __i; + [](_Ret __i) { + return __detail::__to_unsigned_like(__i < 0 ? -__i : __i); }); }(make_index_sequence<sizeof...(_Vs)>{}); } @@ -5071,7 +5071,7 @@ namespace views::__adaptor operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const { if constexpr (sizeof...(_Ts) == 0) - return views::empty<decay_t<invoke_result_t<_Fp>>>; + return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>; else return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...); } @@ -5239,7 +5239,7 @@ namespace views::__adaptor requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> { for (size_t __j = 0; __j < _Nm; ++__j) - _M_current[__j] = std::move(__i[__j]); + _M_current[__j] = std::move(__i._M_current[__j]); } constexpr auto @@ -5762,7 +5762,7 @@ namespace views::__adaptor operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const { if constexpr (_Nm == 0) - return views::empty<tuple<>>; + return zip_transform(std::forward<_Fp>(__f)); else return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm> (std::forward<_Range>(__r), std::forward<_Fp>(__f)); diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error index 0504394..e12bb2f 100644 --- a/libstdc++-v3/include/std/system_error +++ b/libstdc++-v3/include/std/system_error @@ -195,7 +195,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) * @{ */ - error_code make_error_code(errc) noexcept; +namespace __adl_only +{ + void make_error_code() = delete; + void make_error_condition() = delete; +} /** Class error_code * @@ -231,7 +235,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) template<typename _ErrorCodeEnum, typename = _Check<_ErrorCodeEnum>> error_code(_ErrorCodeEnum __e) noexcept - { *this = make_error_code(__e); } + { + using __adl_only::make_error_code; + *this = make_error_code(__e); + } error_code(const error_code&) = default; error_code& operator=(const error_code&) = default; @@ -330,8 +337,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) { return (__os << __e.category().name() << ':' << __e.value()); } - error_condition make_error_condition(errc) noexcept; - /** Class error_condition * * This class represents error conditions that may be visible at an API @@ -363,7 +368,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) template<typename _ErrorConditionEnum, typename = _Check<_ErrorConditionEnum>> error_condition(_ErrorConditionEnum __e) noexcept - { *this = make_error_condition(__e); } + { + using __adl_only::make_error_condition; + *this = make_error_condition(__e); + } error_condition(const error_condition&) = default; error_condition& operator=(const error_condition&) = default; diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index e4d1679..94e73ea 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -289,23 +289,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // __remove_cv_t (std::remove_cv_t for C++11). template<typename _Tp> using __remove_cv_t = typename remove_cv<_Tp>::type; + /// @endcond // Primary type categories. - template<typename> - struct __is_void_helper + /// is_void + template<typename _Tp> + struct is_void : public false_type { }; template<> - struct __is_void_helper<void> + struct is_void<void> : public true_type { }; - /// @endcond - /// is_void - template<typename _Tp> - struct is_void - : public __is_void_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_void<const void> + : public true_type { }; + + template<> + struct is_void<volatile void> + : public true_type { }; + + template<> + struct is_void<const volatile void> + : public true_type { }; /// @cond undocumented template<typename> @@ -571,19 +578,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_is_null_pointer 201309L - template<typename> - struct __is_null_pointer_helper + /// is_null_pointer (LWG 2247). + template<typename _Tp> + struct is_null_pointer : public false_type { }; template<> - struct __is_null_pointer_helper<std::nullptr_t> + struct is_null_pointer<std::nullptr_t> : public true_type { }; - /// is_null_pointer (LWG 2247). - template<typename _Tp> - struct is_null_pointer - : public __is_null_pointer_helper<__remove_cv_t<_Tp>>::type - { }; + template<> + struct is_null_pointer<const std::nullptr_t> + : public true_type { }; + + template<> + struct is_null_pointer<volatile std::nullptr_t> + : public true_type { }; + + template<> + struct is_null_pointer<const volatile std::nullptr_t> + : public true_type { }; /// __is_nullptr_t (deprecated extension). /// @deprecated Non-standard. Use `is_null_pointer` instead. @@ -597,8 +611,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_reference template<typename _Tp> struct is_reference - : public __or_<is_lvalue_reference<_Tp>, - is_rvalue_reference<_Tp>>::type + : public false_type + { }; + + template<typename _Tp> + struct is_reference<_Tp&> + : public true_type + { }; + + template<typename _Tp> + struct is_reference<_Tp&&> + : public true_type { }; /// is_arithmetic diff --git a/libstdc++-v3/libsupc++/dyncast.cc b/libstdc++-v3/libsupc++/dyncast.cc index 853c911..616e4c0 100644 --- a/libstdc++-v3/libsupc++/dyncast.cc +++ b/libstdc++-v3/libsupc++/dyncast.cc @@ -71,6 +71,12 @@ __dynamic_cast (const void *src_ptr, // object started from if (whole_prefix->whole_type != whole_type) return NULL; + // Avoid virtual function call in the simple success case. + if (src2dst >= 0 + && src2dst == -prefix->whole_object + && *whole_type == *dst_type) + return const_cast <void *> (whole_ptr); + whole_type->__do_dyncast (src2dst, __class_type_info::__contained_public, dst_type, whole_ptr, src_type, src_ptr, result); if (!result.dst_ptr) diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc index ede2fe8..86fb8f8 100644 --- a/libstdc++-v3/testsuite/17_intro/names.cc +++ b/libstdc++-v3/testsuite/17_intro/names.cc @@ -129,6 +129,10 @@ // This clashes with newlib so don't use it. # define __lockable cannot be used as an identifier +#ifndef __APPLE__ +#define __weak predefined qualifier on darwin +#define __strong predefined qualifier on darwin +#endif // Common template parameter names #define OutputIterator OutputIterator is not a reserved name diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc new file mode 100644 index 0000000..b1e0b7f --- /dev/null +++ b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc @@ -0,0 +1,48 @@ +// { dg-do compile { target c++11 } } + +// 3629. make_error_code and make_error_condition are customization points +// Verify that make_error_code is looked up using ADL only. + +namespace user +{ + struct E1; +} + +// N.B. not in associated namespace of E1, and declared before <system_error>. +user::E1 make_error_code(user::E1); + +#include <future> // declares std::make_error_code(future_errc) +#include <system_error> + +namespace user +{ + struct E1 + { + operator std::error_code() const; + }; + + struct E2 + { + operator std::future_errc() const; + }; + + struct E3 + { + operator std::errc() const; + }; +} + +template<> struct std::is_error_code_enum<user::E1> : std::true_type { }; +template<> struct std::is_error_code_enum<user::E2> : std::true_type { }; +template<> struct std::is_error_code_enum<user::E3> : std::true_type { }; + +// ::make_error_code(E1) should not be found by name lookup. +std::error_code e1( user::E1{} ); // { dg-error "here" } + +// std::make_error_code(errc) should not be found by name lookup. +std::error_code e2( user::E2{} ); // { dg-error "here" } + +// std::make_error_code(future_errc) should not be found by name lookup. +std::error_code e3( user::E3{} ); // { dg-error "here" } + +// { dg-error "use of deleted function" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc new file mode 100644 index 0000000..e34b53d --- /dev/null +++ b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc @@ -0,0 +1,48 @@ +// { dg-do compile { target c++11 } } + +// 3629. make_error_code and make_error_condition are customization points +// Verify that make_error_condition is looked up using ADL only. + +namespace user +{ + struct E1; +} + +// N.B. not in associated namespace of E1, and declared before <system_error>. +user::E1 make_error_condition(user::E1); + +#include <future> // declares std::make_error_condition(future_errc) +#include <system_error> + +namespace user +{ + struct E1 + { + operator std::error_code() const; + }; + + struct E2 + { + operator std::future_errc() const; + }; + + struct E3 + { + operator std::errc() const; + }; +} + +template<> struct std::is_error_condition_enum<user::E1> : std::true_type { }; +template<> struct std::is_error_condition_enum<user::E2> : std::true_type { }; +template<> struct std::is_error_condition_enum<user::E3> : std::true_type { }; + +// ::make_error_condition(E1) should not be found by name lookup. +std::error_condition e1( user::E1{} ); // { dg-error "here" } + +// std::make_error_condition(errc) should not be found by name lookup. +std::error_condition e2( user::E2{} ); // { dg-error "here" } + +// std::make_error_condition(future_errc) should not be found by name lookup. +std::error_condition e3( user::E3{} ); // { dg-error "here" } + +// { dg-error "use of deleted function" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc index 1870e50..fc0b70b 100644 --- a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc +++ b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc @@ -1,5 +1,7 @@ // { dg-do compile { target c++11 } } // { dg-prune-output "must be a complete" } +// { dg-prune-output "'value' is not a member of 'std::is_move_cons" } +// { dg-prune-output "invalid use of incomplete type" } // Copyright (C) 2019-2022 Free Software Foundation, Inc. // diff --git a/libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete_neg.cc b/libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete_neg.cc index 7bd453d..7c34b5f 100644 --- a/libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete_neg.cc +++ b/libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete_neg.cc @@ -18,6 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-error "must be a complete class" "" { target *-*-* } 0 } +// { dg-prune-output "invalid use of incomplete type" } #include <type_traits> diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/incomplete_neg.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/incomplete_neg.cc index 88c9c01..d3a34cc 100644 --- a/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/incomplete_neg.cc +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/incomplete_neg.cc @@ -18,6 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-error "must be a complete class" "" { target *-*-* } 0 } +// { dg-prune-output "invalid use of incomplete type" } #include <type_traits> diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_swappable_with/incomplete_neg.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable_with/incomplete_neg.cc index da0f771..6dfa336 100644 --- a/libstdc++-v3/testsuite/20_util/is_nothrow_swappable_with/incomplete_neg.cc +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable_with/incomplete_neg.cc @@ -18,6 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-error "must be a complete class" "" { target *-*-* } 0 } +// { dg-prune-output "invalid use of incomplete type" } #include <type_traits> diff --git a/libstdc++-v3/testsuite/20_util/is_swappable_with/incomplete_neg.cc b/libstdc++-v3/testsuite/20_util/is_swappable_with/incomplete_neg.cc index 74ad291..d5fa4225 100644 --- a/libstdc++-v3/testsuite/20_util/is_swappable_with/incomplete_neg.cc +++ b/libstdc++-v3/testsuite/20_util/is_swappable_with/incomplete_neg.cc @@ -18,6 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-error "must be a complete class" "" { target *-*-* } 0 } +// { dg-prune-output "invalid use of incomplete type" } #include <type_traits> diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc new file mode 100644 index 0000000..c4ab876 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc @@ -0,0 +1,42 @@ +// { dg-options "-std=gnu++20" } +// { dg-do run { target c++20 } } +// { dg-add-options libatomic } + +#include <atomic> + +#include <testsuite_hooks.h> + +struct S { char c; short s; }; + +void __attribute__((noinline,noipa)) +fill_struct(S& s) +{ __builtin_memset(&s, 0xff, sizeof(S)); } + +bool +compare_struct(const S& a, const S& b) +{ return __builtin_memcmp(&a, &b, sizeof(S)) == 0; } + +int +main () +{ + S s; + fill_struct(s); + s.c = 'a'; + s.s = 42; + + std::atomic<S> as{ s }; + auto ts = as.load(); + VERIFY( !compare_struct(s, ts) ); // padding cleared on construction + as.exchange(s); + auto es = as.load(); + VERIFY( compare_struct(ts, es) ); // padding cleared on exchange + + S n; + fill_struct(n); + n.c = 'b'; + n.s = 71; + // padding cleared on compexchg + VERIFY( as.compare_exchange_weak(s, n) ); + VERIFY( as.compare_exchange_strong(n, s) ); + return 0; +} diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc new file mode 100644 index 0000000..1b1a12d --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++20" } +// { dg-do run { target c++20 } } +// { dg-add-options libatomic } + +#include <atomic> + +#include <testsuite_hooks.h> + +struct S { char c; short s; }; + +void __attribute__((noinline,noipa)) +fill_struct(S& s) +{ __builtin_memset(&s, 0xff, sizeof(S)); } + +bool +compare_struct(const S& a, const S& b) +{ return __builtin_memcmp(&a, &b, sizeof(S)) == 0; } + +int +main () +{ + S s; + fill_struct(s); + s.c = 'a'; + s.s = 42; + + S ss{ s }; + std::atomic_ref<S> as{ s }; + auto ts = as.load(); + VERIFY( !compare_struct(ss, ts) ); // padding cleared on construction + as.exchange(ss); + auto es = as.load(); + VERIFY( compare_struct(ts, es) ); // padding cleared on exchange + + S n; + fill_struct(n); + n.c = 'b'; + n.s = 71; + // padding cleared on compexchg + VERIFY( as.compare_exchange_weak(s, n) ); + VERIFY( as.compare_exchange_strong(n, s) ); + return 0; +} diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc index cc91803..af335d0 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc @@ -29,7 +29,7 @@ main() // { dg-final { note-test t1 {empty std::tuple} } } std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} }; -// { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = empty std::tuple}} } } +// { dg-final { regexp-test t2 {std::tuple containing = {\[0\] = "Johnny", \[1\] = 5, \[2\] = empty std::tuple}} } } std::cout << "\n"; return 0; // Mark SPOT diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc index f97640a..bc5978e 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc @@ -166,9 +166,9 @@ main() // { dg-final { note-test runiq_ptr {std::unique_ptr<int> = {get() = 0x0}} } } ExTuple tpl(6,7); -// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } } +// { dg-final { note-test tpl {std::tuple containing = {[0] = 6, [1] = 7}} } } ExTuple &rtpl = tpl; -// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } } +// { dg-final { note-test rtpl {std::tuple containing = {[0] = 6, [1] = 7}} } } std::error_code e0; // { dg-final { note-test e0 {std::error_code = { }} } } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc index 9829f79..443c1fb 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc @@ -101,10 +101,22 @@ test03() return true; } +constexpr bool +test04() +{ + // PR libstdc++/106798 + auto r = views::single(0) | views::lazy_split(0) | views::pairwise; + decltype(ranges::cend(r)) s = r.end(); + VERIFY( r.begin() == s ); + + return true; +} + int main() { static_assert(test01()); static_assert(test02()); static_assert(test03()); + static_assert(test04()); } diff --git a/libstdc++-v3/testsuite/std/ranges/zip/1.cc b/libstdc++-v3/testsuite/std/ranges/zip/1.cc index 0113efd..e9e40fb 100644 --- a/libstdc++-v3/testsuite/std/ranges/zip/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/zip/1.cc @@ -102,10 +102,28 @@ test03() return true; } +constexpr bool +test04() +{ + // PR libstdc++/106766 +#if __SIZEOF_INT128__ + auto r = views::zip(views::iota(__int128(0), __int128(1))); +#else + auto r = views::zip(views::iota(0ll, 1ll)); +#endif + auto i = r.begin(); + auto s = r.end(); + VERIFY( s - i == 1 ); + VERIFY( i + 1 - i == 1 ); + + return true; +} + int main() { static_assert(test01()); static_assert(test02()); static_assert(test03()); + static_assert(test04()); } diff --git a/libstdc++-v3/testsuite/util/testsuite_performance.h b/libstdc++-v3/testsuite/util/testsuite_performance.h index 2e05bef..4f8b1ea 100644 --- a/libstdc++-v3/testsuite/util/testsuite_performance.h +++ b/libstdc++-v3/testsuite/util/testsuite_performance.h @@ -36,42 +36,39 @@ #include <testsuite_common_types.h> #if defined (__linux__) || defined (__GLIBC__) -#include <malloc.h> -#elif defined (__FreeBSD__) -extern "C" -{ - struct mallinfo - { - int uordblks; - int hblkhd; - }; +#include <malloc.h> // For mallinfo. +#endif - struct mallinfo - mallinfo(void) - { - struct mallinfo m = { (((std::size_t) sbrk (0) + 1023) / 1024), 0 }; - return m; - } -} -#elif !defined (__hpux__) -extern "C" +namespace __gnu_test { - struct mallinfo + struct MallocInfo { - int uordblks; - int hblkhd; - }; + MallocInfo() : uordblks(0), hblkhd(0) { } + MallocInfo(std::size_t uordblocks, std::size_t hblockhd) + : uordblks(uordblocks), hblkhd(hblockhd) + { } - struct mallinfo empty = { 0, 0 }; + std::size_t uordblks; + std::size_t hblkhd; + }; - struct mallinfo - mallinfo(void) - { return empty; } -} + MallocInfo + malloc_info() + { +#if defined (__linux__) || defined (__hpux__) || defined (__GLIBC__) +#if __GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 33 + struct mallinfo2 mi = mallinfo2(); +#else + struct mallinfo mi = mallinfo(); +#endif + return MallocInfo(mi.uordblks, mi.hblkhd); +#elif defined (__FreeBSD__) + return MallocInfo((((std::size_t) sbrk (0) + 1023) / 1024), 0); +#else + return MallocInfo(); #endif + } -namespace __gnu_test -{ class time_counter { private: @@ -146,8 +143,8 @@ namespace __gnu_test int who; rusage rusage_begin; rusage rusage_end; - struct mallinfo allocation_begin; - struct mallinfo allocation_end; + MallocInfo allocation_begin; + MallocInfo allocation_end; public: resource_counter(int i = RUSAGE_SELF) : who(i) @@ -168,7 +165,7 @@ namespace __gnu_test if (getrusage(who, &rusage_begin) != 0 ) memset(&rusage_begin, 0, sizeof(rusage_begin)); void* p __attribute__((unused)) = malloc(0); // Needed for some implementations. - allocation_begin = mallinfo(); + allocation_begin = malloc_info(); } void @@ -176,7 +173,7 @@ namespace __gnu_test { if (getrusage(who, &rusage_end) != 0 ) memset(&rusage_end, 0, sizeof(rusage_end)); - allocation_end = mallinfo(); + allocation_end = malloc_info(); } int |