diff options
| author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:49:54 +0900 |
|---|---|---|
| committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:49:54 +0900 |
| commit | e2810c9a248f4c7fbfae84bb32b6f7e01027458b (patch) | |
| tree | ae0b02a8491b969a1cee94ea16ffe42c559143c5 /libcxx | |
| parent | fa04eb4af95c1ca7377279728cb004bcd2324d01 (diff) | |
| parent | bdcf47e4bcb92889665825654bb80a8bbe30379e (diff) | |
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/single/switchusers/chapuni/cov/single/switch
Diffstat (limited to 'libcxx')
194 files changed, 1898 insertions, 1101 deletions
diff --git a/libcxx/.clang-tidy b/libcxx/.clang-tidy index f986e2100ca6..ebbfab037926 100644 --- a/libcxx/.clang-tidy +++ b/libcxx/.clang-tidy @@ -5,6 +5,8 @@ Checks: > bugprone-stringview-nullptr, bugprone-use-after-move, + libcpp-*, + llvm-include-order, llvm-namespace-comment, diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst index 4002f40e1dad..d399b94d27c1 100644 --- a/libcxx/docs/Hardening.rst +++ b/libcxx/docs/Hardening.rst @@ -311,7 +311,10 @@ ABI configuration. ABI options ----------- -Vendors can use the following ABI options to enable additional hardening checks: +Vendors can use some ABI options at CMake configuration time (when building libc++ +itself) to enable additional hardening checks. This is done by passing these +macros as ``-DLIBCXX_ABI_DEFINES="_LIBCPP_ABI_FOO;_LIBCPP_ABI_BAR;etc"`` at +CMake configuration time. The available options are: - ``_LIBCPP_ABI_BOUNDED_ITERATORS`` -- changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's @@ -341,7 +344,7 @@ Vendors can use the following ABI options to enable additional hardening checks: ABI impact: changes the iterator type of ``vector`` (except ``vector<bool>``). -- ``_LIBCPP_ABI_BOUNDED_UNIQUE_PTR``` -- tracks the bounds of the array stored inside +- ``_LIBCPP_ABI_BOUNDED_UNIQUE_PTR`` -- tracks the bounds of the array stored inside a ``std::unique_ptr<T[]>``, allowing it to trap when accessed out-of-bounds. This requires the ``std::unique_ptr`` to be created using an API like ``std::make_unique`` or ``std::make_unique_for_overwrite``, otherwise the bounds information is not available @@ -407,7 +410,7 @@ Hardened containers status - ✅ - ❌ * - ``forward_list`` - - ❌ + - ✅ - ❌ * - ``deque`` - ✅ diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst index c8a07fb8b733..ecfbaa5b7a37 100644 --- a/libcxx/docs/ReleaseNotes/20.rst +++ b/libcxx/docs/ReleaseNotes/20.rst @@ -73,6 +73,39 @@ Improvements and New Features optimized, resulting in a performance improvement of up to 2x for trivial element types (e.g., `std::vector<int>`), and up to 3.4x for non-trivial element types (e.g., `std::vector<std::vector<int>>`). +- On Windows, ``<system_error>``'s ``std::system_category`` is now distinct from ``std::generic_category``. The behavior + on other operating systems is unchanged. + + On Windows -- unlike on Unix systems -- the libc and system APIs use distinct error codes. The libc functions return + ``errno.h`` error codes via the ``errno`` global, while Win32 API functions return ``winerror.h`` error codes via + ``GetLastError()``. + + The C++ standard's ``std::error_code`` and ``std::error_category`` functionality was designed to support multiple + error domains, precisely in order to handle situations such as this. However, libc++ formerly treated + ``generic_category()`` and ``system_category()`` as equivalent, even on Windows. It now implements the intended split, + where ``system_category`` represents native ``winerror.h`` error codes, and ``generic_category`` represents libc error + codes (and, equivalently, ``std::errc::*`` errors). + + This change enables code like ``std::error_code(GetLastError(), std::system_category()) == + std::errc::invalid_argument`` to function as desired: constructing an ``error_code`` with the Windows error number in + the "system" category, and then mapping it to a generic code with ``error_condition``, for comparison with the + ``std::errc`` constant. + + This is an incompatible change: ``std::error_code(ENOSYS, std::system_category()) == + std::errc::function_not_supported`` would formerly have returned true, but now returns false on Windows. Code + providing a number from the ``errno.h`` domain should be migrated to construct a ``generic_category`` error_code, + instead. (E.g., use ``std::error_code(ENOSYS, std::generic_category())``). The new behavior matches MSVC. + +- On Windows, the ``std::filesystem`` library now returns the Win32 ``system_category`` error codes, where it's feasible + to do so. This allows interrogation and reporting of the original error code, which is useful if multiple Windows + errors map to a single generic error (such as with ``std::errc::no_such_file_or_directory``). + + This is also a slightly-incompatible API change: code inspecting the raw integer value from the returned error_code + expecting an integer from ``generic_category`` (e.g. ``err.value() == ENOTDIR``) will not work as desired. Instead, + such code should use the comparison operators which implicitly handle eror mappings, ``err == + std::errc::not_a_directory``, or use ``err.default_error_condition()`` to map to an ``error_condition``, and then test + its ``value()`` and ``category()``. + Deprecations and Removals ------------------------- diff --git a/libcxx/docs/TestingLibcxx.rst b/libcxx/docs/TestingLibcxx.rst index cf092fabd046..e98b96bfb478 100644 --- a/libcxx/docs/TestingLibcxx.rst +++ b/libcxx/docs/TestingLibcxx.rst @@ -459,6 +459,29 @@ we only want to make sure they don't rot. Do not rely on the results of benchmar run through ``check-cxx`` for anything, instead run the benchmarks manually using the instructions for running individual tests. +If you want to compare the results of different benchmark runs, we recommend using the +``libcxx-compare-benchmarks`` helper tool. First, configure CMake in a build directory +and run the benchmark: + +.. code-block:: bash + + $ cmake -S runtimes -B <build1> [...] + $ libcxx/utils/libcxx-lit <build1> libcxx/test/benchmarks/string.bench.cpp --param optimization=speed + +Then, do the same for the second configuration you want to test. Use a different build +directory for that configuration: + +.. code-block:: bash + + $ cmake -S runtimes -B <build2> [...] + $ libcxx/utils/libcxx-lit <build2> libcxx/test/benchmarks/string.bench.cpp --param optimization=speed + +Finally, use ``libcxx-compare-benchmarks`` to compare both: + +.. code-block:: bash + + $ libcxx/utils/libcxx-compare-benchmarks <build1> <build2> libcxx/test/benchmarks/string.bench.cpp + .. _`Google Benchmark`: https://github.com/google/benchmark .. _testing-hardening-assertions: diff --git a/libcxx/include/__algorithm/comp_ref_type.h b/libcxx/include/__algorithm/comp_ref_type.h index c367fbb91ac2..6a9d5cef2671 100644 --- a/libcxx/include/__algorithm/comp_ref_type.h +++ b/libcxx/include/__algorithm/comp_ref_type.h @@ -56,10 +56,10 @@ struct __debug_less { // Pass the comparator by lvalue reference. Or in the debug mode, using a debugging wrapper that stores a reference. #if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG template <class _Comp> -using __comp_ref_type = __debug_less<_Comp>; +using __comp_ref_type _LIBCPP_NODEBUG = __debug_less<_Comp>; #else template <class _Comp> -using __comp_ref_type = _Comp&; +using __comp_ref_type _LIBCPP_NODEBUG = _Comp&; #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/copy.h b/libcxx/include/__algorithm/copy.h index 4f30b2050abb..962aa90059d5 100644 --- a/libcxx/include/__algorithm/copy.h +++ b/libcxx/include/__algorithm/copy.h @@ -47,7 +47,7 @@ struct __copy_impl { template <class _InIter, class _OutIter> struct _CopySegment { - using _Traits = __segmented_iterator_traits<_InIter>; + using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_InIter>; _OutIter& __result_; diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h index 6cdb0aec9b2d..e5c89c1e67e3 100644 --- a/libcxx/include/__algorithm/iterator_operations.h +++ b/libcxx/include/__algorithm/iterator_operations.h @@ -48,13 +48,13 @@ struct _RangeAlgPolicy {}; template <> struct _IterOps<_RangeAlgPolicy> { template <class _Iter> - using __value_type = iter_value_t<_Iter>; + using __value_type _LIBCPP_NODEBUG = iter_value_t<_Iter>; template <class _Iter> - using __iterator_category = ranges::__iterator_concept<_Iter>; + using __iterator_category _LIBCPP_NODEBUG = ranges::__iterator_concept<_Iter>; template <class _Iter> - using __difference_type = iter_difference_t<_Iter>; + using __difference_type _LIBCPP_NODEBUG = iter_difference_t<_Iter>; static constexpr auto advance = ranges::advance; static constexpr auto distance = ranges::distance; @@ -72,13 +72,13 @@ struct _ClassicAlgPolicy {}; template <> struct _IterOps<_ClassicAlgPolicy> { template <class _Iter> - using __value_type = typename iterator_traits<_Iter>::value_type; + using __value_type _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::value_type; template <class _Iter> - using __iterator_category = typename iterator_traits<_Iter>::iterator_category; + using __iterator_category _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::iterator_category; template <class _Iter> - using __difference_type = typename iterator_traits<_Iter>::difference_type; + using __difference_type _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type; // advance template <class _Iter, class _Distance> @@ -94,10 +94,10 @@ struct _IterOps<_ClassicAlgPolicy> { } template <class _Iter> - using __deref_t = decltype(*std::declval<_Iter&>()); + using __deref_t _LIBCPP_NODEBUG = decltype(*std::declval<_Iter&>()); template <class _Iter> - using __move_t = decltype(std::move(*std::declval<_Iter&>())); + using __move_t _LIBCPP_NODEBUG = decltype(std::move(*std::declval<_Iter&>())); template <class _Iter> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void __validate_iter_reference() { @@ -217,7 +217,7 @@ private: }; template <class _AlgPolicy, class _Iter> -using __policy_iter_diff_t = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>; +using __policy_iter_diff_t _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/move.h b/libcxx/include/__algorithm/move.h index 005099dcac06..6f3b0eb5d292 100644 --- a/libcxx/include/__algorithm/move.h +++ b/libcxx/include/__algorithm/move.h @@ -50,7 +50,7 @@ struct __move_impl { template <class _InIter, class _OutIter> struct _MoveSegment { - using _Traits = __segmented_iterator_traits<_InIter>; + using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_InIter>; _OutIter& __result_; diff --git a/libcxx/include/__algorithm/ranges_iterator_concept.h b/libcxx/include/__algorithm/ranges_iterator_concept.h index 2af891d3af00..58790e95aa80 100644 --- a/libcxx/include/__algorithm/ranges_iterator_concept.h +++ b/libcxx/include/__algorithm/ranges_iterator_concept.h @@ -44,7 +44,7 @@ consteval auto __get_iterator_concept() { } template <class _Iter> -using __iterator_concept = decltype(__get_iterator_concept<_Iter>()); +using __iterator_concept _LIBCPP_NODEBUG = decltype(__get_iterator_concept<_Iter>()); } // namespace ranges _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/ranges_unique_copy.h b/libcxx/include/__algorithm/ranges_unique_copy.h index 3b4a64e94ca1..ee7f0a0187b7 100644 --- a/libcxx/include/__algorithm/ranges_unique_copy.h +++ b/libcxx/include/__algorithm/ranges_unique_copy.h @@ -60,7 +60,7 @@ struct __unique_copy { } template <class _InIter, class _OutIter> - using __algo_tag_t = decltype(__get_algo_tag<_InIter, _OutIter>()); + using __algo_tag_t _LIBCPP_NODEBUG = decltype(__get_algo_tag<_InIter, _OutIter>()); template <input_iterator _InIter, sentinel_for<_InIter> _Sent, diff --git a/libcxx/include/__algorithm/simd_utils.h b/libcxx/include/__algorithm/simd_utils.h index 4e3e4f2b9404..4e03723a3285 100644 --- a/libcxx/include/__algorithm/simd_utils.h +++ b/libcxx/include/__algorithm/simd_utils.h @@ -70,7 +70,7 @@ struct __get_as_integer_type_impl<8> { }; template <class _Tp> -using __get_as_integer_type_t = typename __get_as_integer_type_impl<sizeof(_Tp)>::type; +using __get_as_integer_type_t _LIBCPP_NODEBUG = typename __get_as_integer_type_impl<sizeof(_Tp)>::type; // This isn't specialized for 64 byte vectors on purpose. They have the potential to significantly reduce performance // in mixed simd/non-simd workloads and don't provide any performance improvement for currently vectorized algorithms @@ -90,7 +90,7 @@ inline constexpr size_t __native_vector_size = 1; # endif template <class _ArithmeticT, size_t _Np> -using __simd_vector __attribute__((__ext_vector_type__(_Np))) = _ArithmeticT; +using __simd_vector __attribute__((__ext_vector_type__(_Np))) _LIBCPP_NODEBUG = _ArithmeticT; template <class _VecT> inline constexpr size_t __simd_vector_size_v = []<bool _False = false>() -> size_t { @@ -106,7 +106,7 @@ _LIBCPP_HIDE_FROM_ABI _Tp __simd_vector_underlying_type_impl(__simd_vector<_Tp, } template <class _VecT> -using __simd_vector_underlying_type_t = decltype(std::__simd_vector_underlying_type_impl(_VecT{})); +using __simd_vector_underlying_type_t _LIBCPP_NODEBUG = decltype(std::__simd_vector_underlying_type_impl(_VecT{})); // This isn't inlined without always_inline when loading chars. template <class _VecT, class _Iter> diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h index ed828b6d7231..5c60b23931cc 100644 --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -890,10 +890,10 @@ __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co } template <class _Type, class... _Options> -using __is_any_of = _Or<is_same<_Type, _Options>...>; +using __is_any_of _LIBCPP_NODEBUG = _Or<is_same<_Type, _Options>...>; template <class _Type> -using __sort_is_specialized_in_library = __is_any_of< +using __sort_is_specialized_in_library _LIBCPP_NODEBUG = __is_any_of< _Type, char, #if _LIBCPP_HAS_WIDE_CHARACTERS diff --git a/libcxx/include/__algorithm/three_way_comp_ref_type.h b/libcxx/include/__algorithm/three_way_comp_ref_type.h index 5702a1fee082..f6f76455e466 100644 --- a/libcxx/include/__algorithm/three_way_comp_ref_type.h +++ b/libcxx/include/__algorithm/three_way_comp_ref_type.h @@ -61,10 +61,10 @@ struct __debug_three_way_comp { // Pass the comparator by lvalue reference. Or in the debug mode, using a debugging wrapper that stores a reference. # if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG template <class _Comp> -using __three_way_comp_ref_type = __debug_three_way_comp<_Comp>; +using __three_way_comp_ref_type _LIBCPP_NODEBUG = __debug_three_way_comp<_Comp>; # else template <class _Comp> -using __three_way_comp_ref_type = _Comp&; +using __three_way_comp_ref_type _LIBCPP_NODEBUG = _Comp&; # endif #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__algorithm/unwrap_iter.h b/libcxx/include/__algorithm/unwrap_iter.h index 8cc0d22d4fc2..b66a682e765f 100644 --- a/libcxx/include/__algorithm/unwrap_iter.h +++ b/libcxx/include/__algorithm/unwrap_iter.h @@ -46,7 +46,7 @@ struct __unwrap_iter_impl { // It's a contiguous iterator, so we can use a raw pointer instead template <class _Iter> struct __unwrap_iter_impl<_Iter, true> { - using _ToAddressT = decltype(std::__to_address(std::declval<_Iter>())); + using _ToAddressT _LIBCPP_NODEBUG = decltype(std::__to_address(std::declval<_Iter>())); static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter __orig_iter, _ToAddressT __unwrapped_iter) { return __orig_iter + (__unwrapped_iter - std::__to_address(__orig_iter)); diff --git a/libcxx/include/__atomic/aliases.h b/libcxx/include/__atomic/aliases.h index 37d11dd0aabf..4fccebab2563 100644 --- a/libcxx/include/__atomic/aliases.h +++ b/libcxx/include/__atomic/aliases.h @@ -84,19 +84,19 @@ using atomic_uintmax_t = atomic<uintmax_t>; // C++20 atomic_{signed,unsigned}_lock_free: prefer the contention type most highly, then the largest lock-free type #if _LIBCPP_STD_VER >= 20 # if ATOMIC_LLONG_LOCK_FREE == 2 -using __largest_lock_free_type = long long; +using __largest_lock_free_type _LIBCPP_NODEBUG = long long; # elif ATOMIC_INT_LOCK_FREE == 2 -using __largest_lock_free_type = int; +using __largest_lock_free_type _LIBCPP_NODEBUG = int; # elif ATOMIC_SHORT_LOCK_FREE == 2 -using __largest_lock_free_type = short; +using __largest_lock_free_type _LIBCPP_NODEBUG = short; # elif ATOMIC_CHAR_LOCK_FREE == 2 -using __largest_lock_free_type = char; +using __largest_lock_free_type _LIBCPP_NODEBUG = char; # else # define _LIBCPP_NO_LOCK_FREE_TYPES // There are no lockfree types (this can happen on unusual platforms) # endif # ifndef _LIBCPP_NO_LOCK_FREE_TYPES -using __contention_t_or_largest = +using __contention_t_or_largest _LIBCPP_NODEBUG = __conditional_t<__libcpp_is_always_lock_free<__cxx_contention_t>::__value, __cxx_contention_t, __largest_lock_free_type>; diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h index 8029b52770d2..975a479e2040 100644 --- a/libcxx/include/__atomic/atomic.h +++ b/libcxx/include/__atomic/atomic.h @@ -143,7 +143,7 @@ struct __atomic_base // false template <class _Tp> struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> { - using __base = __atomic_base<_Tp, false>; + using __base _LIBCPP_NODEBUG = __atomic_base<_Tp, false>; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __atomic_base() _NOEXCEPT = default; @@ -228,9 +228,9 @@ struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > { template <class _Tp> struct atomic : public __atomic_base<_Tp> { - using __base = __atomic_base<_Tp>; - using value_type = _Tp; - using difference_type = value_type; + using __base _LIBCPP_NODEBUG = __atomic_base<_Tp>; + using value_type = _Tp; + using difference_type = value_type; #if _LIBCPP_STD_VER >= 20 _LIBCPP_HIDE_FROM_ABI atomic() = default; @@ -257,9 +257,9 @@ struct atomic : public __atomic_base<_Tp> { template <class _Tp> struct atomic<_Tp*> : public __atomic_base<_Tp*> { - using __base = __atomic_base<_Tp*>; - using value_type = _Tp*; - using difference_type = ptrdiff_t; + using __base _LIBCPP_NODEBUG = __atomic_base<_Tp*>; + using value_type = _Tp*; + using difference_type = ptrdiff_t; _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default; @@ -389,9 +389,9 @@ private: } public: - using __base = __atomic_base<_Tp>; - using value_type = _Tp; - using difference_type = value_type; + using __base _LIBCPP_NODEBUG = __atomic_base<_Tp>; + using value_type = _Tp; + using difference_type = value_type; _LIBCPP_HIDE_FROM_ABI constexpr atomic() noexcept = default; _LIBCPP_HIDE_FROM_ABI constexpr atomic(_Tp __d) noexcept : __base(__d) {} diff --git a/libcxx/include/__atomic/atomic_ref.h b/libcxx/include/__atomic/atomic_ref.h index eef15983b983..177ea646b6cd 100644 --- a/libcxx/include/__atomic/atomic_ref.h +++ b/libcxx/include/__atomic/atomic_ref.h @@ -221,7 +221,7 @@ public: _LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); } protected: - using _Aligned_Tp [[__gnu__::__aligned__(required_alignment)]] = _Tp; + using _Aligned_Tp [[__gnu__::__aligned__(required_alignment), __gnu__::__nodebug__]] = _Tp; _Aligned_Tp* __ptr_; _LIBCPP_HIDE_FROM_ABI __atomic_ref_base(_Tp& __obj) : __ptr_(std::addressof(__obj)) {} @@ -241,7 +241,7 @@ template <class _Tp> struct atomic_ref : public __atomic_ref_base<_Tp> { static_assert(is_trivially_copyable_v<_Tp>, "std::atomic_ref<T> requires that 'T' be a trivially copyable type"); - using __base = __atomic_ref_base<_Tp>; + using __base _LIBCPP_NODEBUG = __atomic_ref_base<_Tp>; _LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp& __obj) : __base(__obj) { _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( @@ -259,7 +259,7 @@ struct atomic_ref : public __atomic_ref_base<_Tp> { template <class _Tp> requires(std::integral<_Tp> && !std::same_as<bool, _Tp>) struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> { - using __base = __atomic_ref_base<_Tp>; + using __base _LIBCPP_NODEBUG = __atomic_ref_base<_Tp>; using difference_type = __base::value_type; @@ -305,7 +305,7 @@ struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> { template <class _Tp> requires std::floating_point<_Tp> struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> { - using __base = __atomic_ref_base<_Tp>; + using __base _LIBCPP_NODEBUG = __atomic_ref_base<_Tp>; using difference_type = __base::value_type; @@ -344,7 +344,7 @@ struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> { template <class _Tp> struct atomic_ref<_Tp*> : public __atomic_ref_base<_Tp*> { - using __base = __atomic_ref_base<_Tp*>; + using __base _LIBCPP_NODEBUG = __atomic_ref_base<_Tp*>; using difference_type = ptrdiff_t; diff --git a/libcxx/include/__atomic/atomic_sync.h b/libcxx/include/__atomic/atomic_sync.h index 153001e7b62e..ab9bc59fdcfe 100644 --- a/libcxx/include/__atomic/atomic_sync.h +++ b/libcxx/include/__atomic/atomic_sync.h @@ -81,7 +81,7 @@ struct __atomic_wait_backoff_impl { _Poll __poll_; memory_order __order_; - using __waitable_traits = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >; + using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >; _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h index 6f2a073bc1a8..5b42a0125f87 100644 --- a/libcxx/include/__atomic/contention_t.h +++ b/libcxx/include/__atomic/contention_t.h @@ -20,12 +20,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) -using __cxx_contention_t = int32_t; +using __cxx_contention_t _LIBCPP_NODEBUG = int32_t; #else -using __cxx_contention_t = int64_t; +using __cxx_contention_t _LIBCPP_NODEBUG = int64_t; #endif // __linux__ || (_AIX && !__64BIT__) -using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; +using __cxx_atomic_contention_t _LIBCPP_NODEBUG = __cxx_atomic_impl<__cxx_contention_t>; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/memory_order.h b/libcxx/include/__atomic/memory_order.h index 294121d1c4e7..44790fe888b3 100644 --- a/libcxx/include/__atomic/memory_order.h +++ b/libcxx/include/__atomic/memory_order.h @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // to pin the underlying type in C++20. enum __legacy_memory_order { __mo_relaxed, __mo_consume, __mo_acquire, __mo_release, __mo_acq_rel, __mo_seq_cst }; -using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type; +using __memory_order_underlying_t _LIBCPP_NODEBUG = underlying_type<__legacy_memory_order>::type; #if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference index 9fa24c98d493..7e27090cc68a 100644 --- a/libcxx/include/__bit_reference +++ b/libcxx/include/__bit_reference @@ -43,8 +43,8 @@ struct __has_storage_type { template <class _Cp, bool = __has_storage_type<_Cp>::value> class __bit_reference { - using __storage_type = typename _Cp::__storage_type; - using __storage_pointer = typename _Cp::__storage_pointer; + using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; + using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__storage_pointer; __storage_pointer __seg_; __storage_type __mask_; @@ -55,7 +55,7 @@ class __bit_reference { friend class __bit_iterator<_Cp, false>; public: - using __container = typename _Cp::__self; + using __container _LIBCPP_NODEBUG = typename _Cp::__self; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default; @@ -135,8 +135,8 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, template <class _Cp> class __bit_const_reference { - using __storage_type = typename _Cp::__storage_type; - using __storage_pointer = typename _Cp::__const_storage_pointer; + using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; + using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__const_storage_pointer; __storage_pointer __seg_; __storage_type __mask_; @@ -145,7 +145,7 @@ class __bit_const_reference { friend class __bit_iterator<_Cp, true>; public: - using __container = typename _Cp::__self; + using __container _LIBCPP_NODEBUG = typename _Cp::__self; _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default; __bit_const_reference& operator=(const __bit_const_reference&) = delete; @@ -587,10 +587,10 @@ inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges( template <class _Cp> struct __bit_array { - using difference_type = typename _Cp::difference_type; - using __storage_type = typename _Cp::__storage_type; - using __storage_pointer = typename _Cp::__storage_pointer; - using iterator = typename _Cp::iterator; + using difference_type _LIBCPP_NODEBUG = typename _Cp::difference_type; + using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; + using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__storage_pointer; + using iterator _LIBCPP_NODEBUG = typename _Cp::iterator; static const unsigned __bits_per_word = _Cp::__bits_per_word; static const unsigned _Np = 4; @@ -790,8 +790,8 @@ public: using iterator_category = random_access_iterator_tag; private: - using __storage_type = typename _Cp::__storage_type; - using __storage_pointer = + using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; + using __storage_pointer _LIBCPP_NODEBUG = __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>; static const unsigned __bits_per_word = _Cp::__bits_per_word; diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h index 3671e6aa52b4..1086dde38195 100644 --- a/libcxx/include/__chrono/formatter.h +++ b/libcxx/include/__chrono/formatter.h @@ -711,7 +711,7 @@ public: template <class _Duration, __fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::sys_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -722,7 +722,7 @@ public: template <class _Duration, __fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::file_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -733,7 +733,7 @@ public: template <class _Duration, __fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::local_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -745,7 +745,7 @@ public: template <class _Rep, class _Period, __fmt_char_type _CharT> struct formatter<chrono::duration<_Rep, _Period>, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -767,7 +767,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::day, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -778,7 +778,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -789,7 +789,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -800,7 +800,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -811,7 +811,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_indexed, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -822,7 +822,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_last, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -833,7 +833,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -844,7 +844,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day_last, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -855,7 +855,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -866,7 +866,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday_last, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -877,7 +877,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -888,7 +888,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -899,7 +899,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day_last, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -910,7 +910,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -921,7 +921,7 @@ public: template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday_last, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -932,7 +932,7 @@ public: template <class _Duration, __fmt_char_type _CharT> struct formatter<chrono::hh_mm_ss<_Duration>, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -944,7 +944,7 @@ public: template <__fmt_char_type _CharT> struct formatter<chrono::sys_info, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -955,7 +955,7 @@ public: template <__fmt_char_type _CharT> struct formatter<chrono::local_info, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -968,7 +968,7 @@ public: template <class _Duration, class _TimeZonePtr, __fmt_char_type _CharT> struct formatter<chrono::zoned_time<_Duration, _TimeZonePtr>, _CharT> : public __formatter_chrono<_CharT> { public: - using _Base = __formatter_chrono<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>; template <class _ParseContext> _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { diff --git a/libcxx/include/__chrono/hh_mm_ss.h b/libcxx/include/__chrono/hh_mm_ss.h index c460b1130508..6ea8a28ee093 100644 --- a/libcxx/include/__chrono/hh_mm_ss.h +++ b/libcxx/include/__chrono/hh_mm_ss.h @@ -30,7 +30,7 @@ template <class _Duration> class hh_mm_ss { private: static_assert(__is_duration_v<_Duration>, "template parameter of hh_mm_ss must be a std::chrono::duration"); - using __CommonType = common_type_t<_Duration, chrono::seconds>; + using __CommonType _LIBCPP_NODEBUG = common_type_t<_Duration, chrono::seconds>; _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) { uint64_t __ret = 1; diff --git a/libcxx/include/__chrono/parser_std_format_spec.h b/libcxx/include/__chrono/parser_std_format_spec.h index 3976864c12b9..4df8e603c6bc 100644 --- a/libcxx/include/__chrono/parser_std_format_spec.h +++ b/libcxx/include/__chrono/parser_std_format_spec.h @@ -140,7 +140,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __validate_time_zone(__flags __flags) { template <class _CharT> class _LIBCPP_TEMPLATE_VIS __parser_chrono { - using _ConstIterator = typename basic_format_parse_context<_CharT>::const_iterator; + using _ConstIterator _LIBCPP_NODEBUG = typename basic_format_parse_context<_CharT>::const_iterator; public: template <class _ParseContext> diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index f57e65c90a62..1deba10d96ae 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -66,7 +66,7 @@ class zoned_time { // Using these constraints in the code causes the compiler to give an // error that the constraint depends on itself. To avoid that issue use // the fact it is possible to create this object from a _TimeZonePtr. - using __traits = zoned_traits<_TimeZonePtr>; + using __traits _LIBCPP_NODEBUG = zoned_traits<_TimeZonePtr>; public: using duration = common_type_t<_Duration, seconds>; @@ -186,7 +186,7 @@ template <class _Duration> zoned_time(sys_time<_Duration>) -> zoned_time<common_type_t<_Duration, seconds>>; template <class _TimeZonePtrOrName> -using __time_zone_representation = +using __time_zone_representation _LIBCPP_NODEBUG = conditional_t<is_convertible_v<_TimeZonePtrOrName, string_view>, const time_zone*, remove_cvref_t<_TimeZonePtrOrName>>; diff --git a/libcxx/include/__compare/ordering.h b/libcxx/include/__compare/ordering.h index 297218e6f29e..902ef5329dd4 100644 --- a/libcxx/include/__compare/ordering.h +++ b/libcxx/include/__compare/ordering.h @@ -120,7 +120,7 @@ inline constexpr partial_ordering partial_ordering::greater(_PartialOrdResult::_ inline constexpr partial_ordering partial_ordering::unordered(_PartialOrdResult::__unordered); class weak_ordering { - using _ValueT = signed char; + using _ValueT _LIBCPP_NODEBUG = signed char; _LIBCPP_HIDE_FROM_ABI explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} @@ -190,7 +190,7 @@ inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv); inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); class strong_ordering { - using _ValueT = signed char; + using _ValueT _LIBCPP_NODEBUG = signed char; _LIBCPP_HIDE_FROM_ABI explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} diff --git a/libcxx/include/__compare/synth_three_way.h b/libcxx/include/__compare/synth_three_way.h index e48ce4979983..63bf56d0cf42 100644 --- a/libcxx/include/__compare/synth_three_way.h +++ b/libcxx/include/__compare/synth_three_way.h @@ -43,7 +43,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = []<class _Tp, cl }; template <class _Tp, class _Up = _Tp> -using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>())); +using __synth_three_way_result _LIBCPP_NODEBUG = + decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>())); #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h index 7df46a0e94dc..6257e6f729bf 100644 --- a/libcxx/include/__exception/exception_ptr.h +++ b/libcxx/include/__exception/exception_ptr.h @@ -66,7 +66,7 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr { public: // exception_ptr is basically a COW string. - using __trivially_relocatable = exception_ptr; + using __trivially_relocatable _LIBCPP_NODEBUG = exception_ptr; _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {} _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h index 3d3f11967ee7..03bbd1623ed5 100644 --- a/libcxx/include/__expected/expected.h +++ b/libcxx/include/__expected/expected.h @@ -459,14 +459,14 @@ class expected : private __expected_base<_Tp, _Err> { template <class _Up, class _OtherErr> friend class expected; - using __base = __expected_base<_Tp, _Err>; + using __base _LIBCPP_NODEBUG = __expected_base<_Tp, _Err>; public: using value_type = _Tp; using error_type = _Err; using unexpected_type = unexpected<_Err>; - using __trivially_relocatable = + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value, expected, void>; @@ -505,7 +505,7 @@ public: private: template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual> - using __can_convert = _And< + using __can_convert _LIBCPP_NODEBUG = _And< is_constructible<_Tp, _UfQual>, is_constructible<_Err, _OtherErrQual>, _If<_Not<is_same<remove_cv_t<_Tp>, bool>>::value, @@ -1363,7 +1363,7 @@ class expected<_Tp, _Err> : private __expected_void_base<_Err> { friend class expected; template <class _Up, class _OtherErr, class _OtherErrQual> - using __can_convert = + using __can_convert _LIBCPP_NODEBUG = _And< is_void<_Up>, is_constructible<_Err, _OtherErrQual>, _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>, @@ -1371,7 +1371,7 @@ class expected<_Tp, _Err> : private __expected_void_base<_Err> { _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>, _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>; - using __base = __expected_void_base<_Err>; + using __base _LIBCPP_NODEBUG = __expected_void_base<_Err>; public: using value_type = _Tp; diff --git a/libcxx/include/__expected/unexpected.h b/libcxx/include/__expected/unexpected.h index cf110bcf69a8..6904889b8c6b 100644 --- a/libcxx/include/__expected/unexpected.h +++ b/libcxx/include/__expected/unexpected.h @@ -48,12 +48,12 @@ template <class _Err> struct __is_std_unexpected<unexpected<_Err>> : true_type {}; template <class _Tp> -using __valid_std_unexpected = _BoolConstant< // - is_object_v<_Tp> && // - !is_array_v<_Tp> && // - !__is_std_unexpected<_Tp>::value && // - !is_const_v<_Tp> && // - !is_volatile_v<_Tp> // +using __valid_std_unexpected _LIBCPP_NODEBUG = _BoolConstant< // + is_object_v<_Tp> && // + !is_array_v<_Tp> && // + !__is_std_unexpected<_Tp>::value && // + !is_const_v<_Tp> && // + !is_volatile_v<_Tp> // >; template <class _Err> diff --git a/libcxx/include/__filesystem/directory_entry.h b/libcxx/include/__filesystem/directory_entry.h index 7d0c01b98def..11e07acdbe00 100644 --- a/libcxx/include/__filesystem/directory_entry.h +++ b/libcxx/include/__filesystem/directory_entry.h @@ -22,7 +22,9 @@ #include <__filesystem/perms.h> #include <__fwd/ostream.h> #include <__system_error/errc.h> +#include <__system_error/error_category.h> #include <__system_error/error_code.h> +#include <__system_error/error_condition.h> #include <__utility/move.h> #include <__utility/unreachable.h> #include <cstdint> @@ -274,15 +276,7 @@ private: _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept; _LIBCPP_HIDE_FROM_ABI static bool __is_dne_error(error_code const& __ec) { - if (!__ec) - return true; - switch (static_cast<errc>(__ec.value())) { - case errc::no_such_file_or_directory: - case errc::not_a_directory: - return true; - default: - return false; - } + return !__ec || __ec == errc::no_such_file_or_directory || __ec == errc::not_a_directory; } _LIBCPP_HIDE_FROM_ABI void diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h index 509d1cc8052f..0a751ba32954 100644 --- a/libcxx/include/__filesystem/path.h +++ b/libcxx/include/__filesystem/path.h @@ -51,30 +51,30 @@ template <class _Tp> struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {}; template <> struct __can_convert_char<char> { - static const bool value = true; - using __char_type = char; + static const bool value = true; + using __char_type _LIBCPP_NODEBUG = char; }; template <> struct __can_convert_char<wchar_t> { - static const bool value = true; - using __char_type = wchar_t; + static const bool value = true; + using __char_type _LIBCPP_NODEBUG = wchar_t; }; # if _LIBCPP_HAS_CHAR8_T template <> struct __can_convert_char<char8_t> { - static const bool value = true; - using __char_type = char8_t; + static const bool value = true; + using __char_type _LIBCPP_NODEBUG = char8_t; }; # endif template <> struct __can_convert_char<char16_t> { - static const bool value = true; - using __char_type = char16_t; + static const bool value = true; + using __char_type _LIBCPP_NODEBUG = char16_t; }; template <> struct __can_convert_char<char32_t> { - static const bool value = true; - using __char_type = char32_t; + static const bool value = true; + using __char_type _LIBCPP_NODEBUG = char32_t; }; template <class _ECharT, __enable_if_t<__can_convert_char<_ECharT>::value, int> = 0> @@ -95,7 +95,7 @@ typedef string __u8_string; struct _NullSentinel {}; template <class _Tp> -using _Void = void; +using _Void _LIBCPP_NODEBUG = void; template <class _Tp, class = void> struct __is_pathable_string : public false_type {}; @@ -104,7 +104,7 @@ template <class _ECharT, class _Traits, class _Alloc> struct __is_pathable_string< basic_string<_ECharT, _Traits, _Alloc>, _Void<typename __can_convert_char<_ECharT>::__char_type> > : public __can_convert_char<_ECharT> { - using _Str = basic_string<_ECharT, _Traits, _Alloc>; + using _Str _LIBCPP_NODEBUG = basic_string<_ECharT, _Traits, _Alloc>; _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } @@ -117,7 +117,7 @@ template <class _ECharT, class _Traits> struct __is_pathable_string< basic_string_view<_ECharT, _Traits>, _Void<typename __can_convert_char<_ECharT>::__char_type> > : public __can_convert_char<_ECharT> { - using _Str = basic_string_view<_ECharT, _Traits>; + using _Str _LIBCPP_NODEBUG = basic_string_view<_ECharT, _Traits>; _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } @@ -157,7 +157,7 @@ struct __is_pathable_iter< true, _Void<typename __can_convert_char< typename iterator_traits<_Iter>::value_type>::__char_type> > : __can_convert_char<typename iterator_traits<_Iter>::value_type> { - using _ECharT = typename iterator_traits<_Iter>::value_type; + using _ECharT _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::value_type; _LIBCPP_HIDE_FROM_ABI static _Iter __range_begin(_Iter __b) { return __b; } @@ -380,13 +380,13 @@ struct _PathExport<char8_t> { class _LIBCPP_EXPORTED_FROM_ABI path { template <class _SourceOrIter, class _Tp = path&> - using _EnableIfPathable = __enable_if_t<__is_pathable<_SourceOrIter>::value, _Tp>; + using _EnableIfPathable _LIBCPP_NODEBUG = __enable_if_t<__is_pathable<_SourceOrIter>::value, _Tp>; template <class _Tp> - using _SourceChar = typename __is_pathable<_Tp>::__char_type; + using _SourceChar _LIBCPP_NODEBUG = typename __is_pathable<_Tp>::__char_type; template <class _Tp> - using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; + using _SourceCVT _LIBCPP_NODEBUG = _PathCVT<_SourceChar<_Tp> >; public: # if defined(_LIBCPP_WIN32API) diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h index b66bc1cb66fc..9fe84250b120 100644 --- a/libcxx/include/__flat_map/flat_map.h +++ b/libcxx/include/__flat_map/flat_map.h @@ -90,7 +90,7 @@ class flat_map { static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container"); template <bool _Const> - using __iterator = __key_value_iterator<flat_map, _KeyContainer, _MappedContainer, _Const>; + using __iterator _LIBCPP_NODEBUG = __key_value_iterator<flat_map, _KeyContainer, _MappedContainer, _Const>; public: // types diff --git a/libcxx/include/__flat_map/key_value_iterator.h b/libcxx/include/__flat_map/key_value_iterator.h index 987ac677a413..06a23f342997 100644 --- a/libcxx/include/__flat_map/key_value_iterator.h +++ b/libcxx/include/__flat_map/key_value_iterator.h @@ -41,9 +41,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Owner, class _KeyContainer, class _MappedContainer, bool _Const> struct __key_value_iterator { private: - using __key_iterator = ranges::iterator_t<const _KeyContainer>; - using __mapped_iterator = ranges::iterator_t<__maybe_const<_Const, _MappedContainer>>; - using __reference = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>; + using __key_iterator _LIBCPP_NODEBUG = ranges::iterator_t<const _KeyContainer>; + using __mapped_iterator _LIBCPP_NODEBUG = ranges::iterator_t<__maybe_const<_Const, _MappedContainer>>; + using __reference _LIBCPP_NODEBUG = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>; struct __arrow_proxy { __reference __ref_; diff --git a/libcxx/include/__format/buffer.h b/libcxx/include/__format/buffer.h index 618b8ef02564..9509f19e1672 100644 --- a/libcxx/include/__format/buffer.h +++ b/libcxx/include/__format/buffer.h @@ -322,7 +322,7 @@ struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container<back_insert_iterato template <class _Container> class _LIBCPP_TEMPLATE_VIS __writer_container { public: - using _CharT = typename _Container::value_type; + using _CharT _LIBCPP_NODEBUG = typename _Container::value_type; _LIBCPP_HIDE_FROM_ABI explicit __writer_container(back_insert_iterator<_Container> __out_it) : __container_{__out_it.__get_container()} {} @@ -340,7 +340,7 @@ private: /// Selects the type of the writer used for the output iterator. template <class _OutIt, class _CharT> class _LIBCPP_TEMPLATE_VIS __writer_selector { - using _Container = typename __back_insert_iterator_container<_OutIt>::type; + using _Container _LIBCPP_NODEBUG = typename __back_insert_iterator_container<_OutIt>::type; public: using type = @@ -355,7 +355,7 @@ public: template <class _OutIt, __fmt_char_type _CharT> requires(output_iterator<_OutIt, const _CharT&>) class _LIBCPP_TEMPLATE_VIS __format_buffer { - using _Storage = + using _Storage _LIBCPP_NODEBUG = conditional_t<__enable_direct_output<_OutIt, _CharT>, __direct_storage<_CharT>, __internal_storage<_CharT>>; public: @@ -408,7 +408,7 @@ private: template <class _OutIt, __fmt_char_type _CharT, bool> requires(output_iterator<_OutIt, const _CharT&>) struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base { - using _Size = iter_difference_t<_OutIt>; + using _Size _LIBCPP_NODEBUG = iter_difference_t<_OutIt>; public: _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) @@ -438,7 +438,7 @@ protected: template <class _OutIt, __fmt_char_type _CharT> requires(output_iterator<_OutIt, const _CharT&>) class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base<_OutIt, _CharT, true> { - using _Size = iter_difference_t<_OutIt>; + using _Size _LIBCPP_NODEBUG = iter_difference_t<_OutIt>; public: _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) @@ -489,8 +489,8 @@ template <class _OutIt, __fmt_char_type _CharT> requires(output_iterator<_OutIt, const _CharT&>) struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer final : public __format_to_n_buffer_base< _OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>> { - using _Base = __format_to_n_buffer_base<_OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>>; - using _Size = iter_difference_t<_OutIt>; + using _Base _LIBCPP_NODEBUG = __format_to_n_buffer_base<_OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>>; + using _Size _LIBCPP_NODEBUG = iter_difference_t<_OutIt>; public: _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer(_OutIt __out_it, _Size __max_size) @@ -523,7 +523,7 @@ public: // would lead to a circular include with formatter for vector<bool>. template <__fmt_char_type _CharT> class _LIBCPP_TEMPLATE_VIS __retarget_buffer { - using _Alloc = allocator<_CharT>; + using _Alloc _LIBCPP_NODEBUG = allocator<_CharT>; public: using value_type = _CharT; diff --git a/libcxx/include/__format/concepts.h b/libcxx/include/__format/concepts.h index 2c40e3e31491..28297c612db7 100644 --- a/libcxx/include/__format/concepts.h +++ b/libcxx/include/__format/concepts.h @@ -44,7 +44,7 @@ concept __fmt_char_type = // (Note testing for (w)format_context would be a valid choice, but requires // selecting the proper one depending on the type of _CharT.) template <class _CharT> -using __fmt_iter_for = _CharT*; +using __fmt_iter_for _LIBCPP_NODEBUG = _CharT*; template <class _Tp, class _Context, class _Formatter = typename _Context::template formatter_type<remove_const_t<_Tp>>> concept __formattable_with = diff --git a/libcxx/include/__format/container_adaptor.h b/libcxx/include/__format/container_adaptor.h index d3be2e189560..48d42ee7d901 100644 --- a/libcxx/include/__format/container_adaptor.h +++ b/libcxx/include/__format/container_adaptor.h @@ -37,8 +37,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Adaptor, class _CharT> struct _LIBCPP_TEMPLATE_VIS __formatter_container_adaptor { private: - using __maybe_const_container = __fmt_maybe_const<typename _Adaptor::container_type, _CharT>; - using __maybe_const_adaptor = __maybe_const<is_const_v<__maybe_const_container>, _Adaptor>; + using __maybe_const_container _LIBCPP_NODEBUG = __fmt_maybe_const<typename _Adaptor::container_type, _CharT>; + using __maybe_const_adaptor _LIBCPP_NODEBUG = __maybe_const<is_const_v<__maybe_const_container>, _Adaptor>; formatter<ranges::ref_view<__maybe_const_container>, _CharT> __underlying_; public: diff --git a/libcxx/include/__format/format_arg.h b/libcxx/include/__format/format_arg.h index a973ccd43c42..1c530fd5a5d0 100644 --- a/libcxx/include/__format/format_arg.h +++ b/libcxx/include/__format/format_arg.h @@ -208,7 +208,7 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg< /// separate arrays. template <class _Context> class __basic_format_arg_value { - using _CharT = typename _Context::char_type; + using _CharT _LIBCPP_NODEBUG = typename _Context::char_type; public: /// Contains the implementation for basic_format_arg::handle. diff --git a/libcxx/include/__format/format_arg_store.h b/libcxx/include/__format/format_arg_store.h index 8b2c95c657c9..4c5ee9e9e4fd 100644 --- a/libcxx/include/__format/format_arg_store.h +++ b/libcxx/include/__format/format_arg_store.h @@ -257,7 +257,7 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store { } } - using _Storage = + using _Storage _LIBCPP_NODEBUG = conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)), __format::__packed_format_arg_store<_Context, sizeof...(_Args)>, __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>; diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h index 3991363c0124..b920be5acbe8 100644 --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -379,7 +379,7 @@ struct _LIBCPP_TEMPLATE_VIS basic_format_string { private: basic_string_view<_CharT> __str_; - using _Context = __format::__compile_time_basic_format_context<_CharT>; + using _Context _LIBCPP_NODEBUG = __format::__compile_time_basic_format_context<_CharT>; static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{ __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...}; diff --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h index e04fffb683c3..ac4be9b61935 100644 --- a/libcxx/include/__format/formatter_floating_point.h +++ b/libcxx/include/__format/formatter_floating_point.h @@ -141,7 +141,7 @@ struct __traits<double> { /// on the stack or the heap. template <floating_point _Fp> class _LIBCPP_TEMPLATE_VIS __float_buffer { - using _Traits = __traits<_Fp>; + using _Traits _LIBCPP_NODEBUG = __traits<_Fp>; public: // TODO FMT Improve this constructor to do a better estimate. diff --git a/libcxx/include/__format/formatter_string.h b/libcxx/include/__format/formatter_string.h index 826d6421c863..30084e582214 100644 --- a/libcxx/include/__format/formatter_string.h +++ b/libcxx/include/__format/formatter_string.h @@ -59,7 +59,7 @@ public: // Formatter const char*. template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT> : public __formatter_string<_CharT> { - using _Base = __formatter_string<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>; template <class _FormatContext> _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const { @@ -78,7 +78,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT> : public __formatte // Formatter char*. template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> : public formatter<const _CharT*, _CharT> { - using _Base = formatter<const _CharT*, _CharT>; + using _Base _LIBCPP_NODEBUG = formatter<const _CharT*, _CharT>; template <class _FormatContext> _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT* __str, _FormatContext& __ctx) const { @@ -89,7 +89,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> : public formatter<const // Formatter char[]. template <__fmt_char_type _CharT, size_t _Size> struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> : public __formatter_string<_CharT> { - using _Base = __formatter_string<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>; template <class _FormatContext> _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator @@ -102,7 +102,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> : public __formatte template <__fmt_char_type _CharT, class _Traits, class _Allocator> struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT> : public __formatter_string<_CharT> { - using _Base = __formatter_string<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>; template <class _FormatContext> _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator @@ -115,7 +115,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>, // Formatter std::string_view. template <__fmt_char_type _CharT, class _Traits> struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT> : public __formatter_string<_CharT> { - using _Base = __formatter_string<_CharT>; + using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>; template <class _FormatContext> _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator diff --git a/libcxx/include/__format/range_default_formatter.h b/libcxx/include/__format/range_default_formatter.h index fb21b0f8beb3..bb4c520f5ea1 100644 --- a/libcxx/include/__format/range_default_formatter.h +++ b/libcxx/include/__format/range_default_formatter.h @@ -40,7 +40,7 @@ concept __const_formattable_range = ranges::input_range<const _Rp> && formattable<ranges::range_reference_t<const _Rp>, _CharT>; template <class _Rp, class _CharT> -using __fmt_maybe_const = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>; +using __fmt_maybe_const _LIBCPP_NODEBUG = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>; _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow") @@ -95,7 +95,7 @@ struct _LIBCPP_TEMPLATE_VIS __range_default_formatter; template <ranges::input_range _Rp, class _CharT> struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::sequence, _Rp, _CharT> { private: - using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>; + using __maybe_const_r _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>; range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_; public: @@ -122,8 +122,8 @@ public: template <ranges::input_range _Rp, class _CharT> struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::map, _Rp, _CharT> { private: - using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>; - using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>; + using __maybe_const_map _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>; + using __element_type _LIBCPP_NODEBUG = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>; range_formatter<__element_type, _CharT> __underlying_; public: @@ -150,8 +150,8 @@ public: template <ranges::input_range _Rp, class _CharT> struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::set, _Rp, _CharT> { private: - using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>; - using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>; + using __maybe_const_set _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>; + using __element_type _LIBCPP_NODEBUG = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>; range_formatter<__element_type, _CharT> __underlying_; public: diff --git a/libcxx/include/__format/unicode.h b/libcxx/include/__format/unicode.h index b4f22c739d6a..46096fda1e8a 100644 --- a/libcxx/include/__format/unicode.h +++ b/libcxx/include/__format/unicode.h @@ -123,7 +123,7 @@ class __code_point_view; /// UTF-8 specialization. template <> class __code_point_view<char> { - using _Iterator = basic_string_view<char>::const_iterator; + using _Iterator _LIBCPP_NODEBUG = basic_string_view<char>::const_iterator; public: _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last) @@ -249,7 +249,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_low(wchar_t __value) { /// - 4 UTF-32 (for example Linux) template <> class __code_point_view<wchar_t> { - using _Iterator = typename basic_string_view<wchar_t>::const_iterator; + using _Iterator _LIBCPP_NODEBUG = typename basic_string_view<wchar_t>::const_iterator; public: static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value"); @@ -300,8 +300,8 @@ private: // This implements the extended rules see // https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries class __extended_grapheme_cluster_break { - using __EGC_property = __extended_grapheme_custer_property_boundary::__property; - using __inCB_property = __indic_conjunct_break::__property; + using __EGC_property _LIBCPP_NODEBUG = __extended_grapheme_custer_property_boundary::__property; + using __inCB_property _LIBCPP_NODEBUG = __indic_conjunct_break::__property; public: _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_break(char32_t __first_code_point) @@ -527,7 +527,7 @@ private: /// Therefore only this code point is extracted. template <class _CharT> class __extended_grapheme_cluster_view { - using _Iterator = typename basic_string_view<_CharT>::const_iterator; + using _Iterator _LIBCPP_NODEBUG = typename basic_string_view<_CharT>::const_iterator; public: _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last) @@ -572,7 +572,7 @@ __extended_grapheme_cluster_view(_Iterator, _Iterator) -> __extended_grapheme_cl // This makes it easier to write code agnostic of the _LIBCPP_HAS_UNICODE define. template <class _CharT> class __code_point_view { - using _Iterator = typename basic_string_view<_CharT>::const_iterator; + using _Iterator _LIBCPP_NODEBUG = typename basic_string_view<_CharT>::const_iterator; public: _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last) diff --git a/libcxx/include/__functional/binary_function.h b/libcxx/include/__functional/binary_function.h index ddee3b170311..bde8b03ef828 100644 --- a/libcxx/include/__functional/binary_function.h +++ b/libcxx/include/__functional/binary_function.h @@ -42,11 +42,11 @@ struct __binary_function_keep_layout_base { _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") template <class _Arg1, class _Arg2, class _Result> -using __binary_function = binary_function<_Arg1, _Arg2, _Result>; +using __binary_function _LIBCPP_NODEBUG = binary_function<_Arg1, _Arg2, _Result>; _LIBCPP_DIAGNOSTIC_POP #else template <class _Arg1, class _Arg2, class _Result> -using __binary_function = __binary_function_keep_layout_base<_Arg1, _Arg2, _Result>; +using __binary_function _LIBCPP_NODEBUG = __binary_function_keep_layout_base<_Arg1, _Arg2, _Result>; #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h index f82c1517249b..e31ad2979035 100644 --- a/libcxx/include/__functional/bind.h +++ b/libcxx/include/__functional/bind.h @@ -198,7 +198,7 @@ __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, _ template <class _Fp, class... _BoundArgs> class __bind : public __weak_result_type<__decay_t<_Fp> > { protected: - using _Fd = __decay_t<_Fp>; + using _Fd _LIBCPP_NODEBUG = __decay_t<_Fp>; typedef tuple<__decay_t<_BoundArgs>...> _Td; private: diff --git a/libcxx/include/__functional/boyer_moore_searcher.h b/libcxx/include/__functional/boyer_moore_searcher.h index 52a58d57a8d4..1e49cc5464be 100644 --- a/libcxx/include/__functional/boyer_moore_searcher.h +++ b/libcxx/include/__functional/boyer_moore_searcher.h @@ -92,7 +92,7 @@ class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { private: using difference_type = typename std::iterator_traits<_RandomAccessIterator1>::difference_type; using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type; - using __skip_table_type = + using __skip_table_type _LIBCPP_NODEBUG = _BMSkipTable<value_type, difference_type, _Hash, @@ -223,7 +223,7 @@ class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { private: using difference_type = typename iterator_traits<_RandomAccessIterator1>::difference_type; using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type; - using __skip_table_type = + using __skip_table_type _LIBCPP_NODEBUG = _BMSkipTable<value_type, difference_type, _Hash, diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h index a421a3ef4f5f..b483e8ea8f85 100644 --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -576,7 +576,7 @@ private: // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is // faster for types that can be passed in registers. template <typename _Tp> -using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>; +using __fast_forward _LIBCPP_NODEBUG = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>; // __policy_invoker calls an instance of __alloc_func held in __policy_storage. @@ -847,7 +847,7 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> }; template <class _Fp> - using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>; + using _EnableIfLValueCallable _LIBCPP_NODEBUG = __enable_if_t<__callable<_Fp&>::value>; public: typedef _Rp result_type; diff --git a/libcxx/include/__functional/perfect_forward.h b/libcxx/include/__functional/perfect_forward.h index 8fd68db3d6eb..37c3d15b4bec 100644 --- a/libcxx/include/__functional/perfect_forward.h +++ b/libcxx/include/__functional/perfect_forward.h @@ -94,7 +94,7 @@ public: // __perfect_forward implements a perfect-forwarding call wrapper as explained in [func.require]. template <class _Op, class... _Args> -using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; +using __perfect_forward _LIBCPP_NODEBUG = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; #endif // _LIBCPP_STD_VER >= 17 diff --git a/libcxx/include/__functional/unary_function.h b/libcxx/include/__functional/unary_function.h index 69b1bc94220a..769ffc9893a7 100644 --- a/libcxx/include/__functional/unary_function.h +++ b/libcxx/include/__functional/unary_function.h @@ -39,11 +39,11 @@ struct __unary_function_keep_layout_base { _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") template <class _Arg, class _Result> -using __unary_function = unary_function<_Arg, _Result>; +using __unary_function _LIBCPP_NODEBUG = unary_function<_Arg, _Result>; _LIBCPP_DIAGNOSTIC_POP #else template <class _Arg, class _Result> -using __unary_function = __unary_function_keep_layout_base<_Arg, _Result>; +using __unary_function _LIBCPP_NODEBUG = __unary_function_keep_layout_base<_Arg, _Result>; #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 9c821ea69081..7788f687746f 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -111,8 +111,8 @@ struct __hash_node_base { template <class _Tp, class _VoidPtr> struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > { typedef _Tp __node_value_type; - using _Base = __hash_node_base<__rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > >; - using __next_pointer = typename _Base::__next_pointer; + using _Base _LIBCPP_NODEBUG = __hash_node_base<__rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > >; + using __next_pointer _LIBCPP_NODEBUG = typename _Base::__next_pointer; size_t __hash_; diff --git a/libcxx/include/__iterator/aliasing_iterator.h b/libcxx/include/__iterator/aliasing_iterator.h index aeb5b4a88ec3..e01127142ae9 100644 --- a/libcxx/include/__iterator/aliasing_iterator.h +++ b/libcxx/include/__iterator/aliasing_iterator.h @@ -31,8 +31,8 @@ struct __aliasing_iterator_wrapper { class __iterator { _BaseIter __base_ = nullptr; - using __iter_traits = iterator_traits<_BaseIter>; - using __base_value_type = typename __iter_traits::value_type; + using __iter_traits _LIBCPP_NODEBUG = iterator_traits<_BaseIter>; + using __base_value_type _LIBCPP_NODEBUG = typename __iter_traits::value_type; static_assert(__has_random_access_iterator_category<_BaseIter>::value, "The base iterator has to be a random access iterator!"); @@ -120,7 +120,7 @@ struct __aliasing_iterator_wrapper { // This is required to avoid ADL instantiations on _BaseT template <class _BaseT, class _Alias> -using __aliasing_iterator = typename __aliasing_iterator_wrapper<_BaseT, _Alias>::__iterator; +using __aliasing_iterator _LIBCPP_NODEBUG = typename __aliasing_iterator_wrapper<_BaseT, _Alias>::__iterator; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h index 1c227933a482..6e5ac1d3af37 100644 --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -67,10 +67,10 @@ template <class _In> concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In>>; template <class _Tp> -using __projected_iterator_t = typename _Tp::__projected_iterator; +using __projected_iterator_t _LIBCPP_NODEBUG = typename _Tp::__projected_iterator; template <class _Tp> -using __projected_projection_t = typename _Tp::__projected_projection; +using __projected_projection_t _LIBCPP_NODEBUG = typename _Tp::__projected_projection; template <class _Tp> concept __specialization_of_projected = requires { @@ -89,7 +89,7 @@ struct __indirect_value_t_impl<_Tp> { }; template <indirectly_readable _Tp> -using __indirect_value_t = typename __indirect_value_t_impl<_Tp>::type; +using __indirect_value_t _LIBCPP_NODEBUG = typename __indirect_value_t_impl<_Tp>::type; template <indirectly_readable _Tp> using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, __indirect_value_t<_Tp>>; @@ -274,7 +274,7 @@ concept indirectly_copyable_storable = #endif // _LIBCPP_STD_VER >= 20 template <class _Tp> -using __has_random_access_iterator_category_or_concept +using __has_random_access_iterator_category_or_concept _LIBCPP_NODEBUG #if _LIBCPP_STD_VER >= 20 = integral_constant<bool, random_access_iterator<_Tp>>; #else // _LIBCPP_STD_VER < 20 diff --git a/libcxx/include/__iterator/insert_iterator.h b/libcxx/include/__iterator/insert_iterator.h index b3311042014f..e0ee0ce035e2 100644 --- a/libcxx/include/__iterator/insert_iterator.h +++ b/libcxx/include/__iterator/insert_iterator.h @@ -29,10 +29,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template <class _Container> -using __insert_iterator_iter_t = ranges::iterator_t<_Container>; +using __insert_iterator_iter_t _LIBCPP_NODEBUG = ranges::iterator_t<_Container>; #else template <class _Container> -using __insert_iterator_iter_t = typename _Container::iterator; +using __insert_iterator_iter_t _LIBCPP_NODEBUG = typename _Container::iterator; #endif _LIBCPP_SUPPRESS_DEPRECATED_PUSH diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h index eb6ba8b62fb3..db68dd2c377a 100644 --- a/libcxx/include/__iterator/iterator_traits.h +++ b/libcxx/include/__iterator/iterator_traits.h @@ -47,7 +47,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template <class _Tp> -using __with_reference = _Tp&; +using __with_reference _LIBCPP_NODEBUG = _Tp&; template <class _Tp> concept __can_reference = requires { typename __with_reference<_Tp>; }; @@ -80,19 +80,20 @@ struct __iter_traits_cache { using type = _If< __is_primary_template<iterator_traits<_Iter> >::value, _Iter, iterator_traits<_Iter> >; }; template <class _Iter> -using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type; +using _ITER_TRAITS _LIBCPP_NODEBUG = typename __iter_traits_cache<_Iter>::type; struct __iter_concept_concept_test { template <class _Iter> - using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept; + using _Apply _LIBCPP_NODEBUG = typename _ITER_TRAITS<_Iter>::iterator_concept; }; struct __iter_concept_category_test { template <class _Iter> - using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category; + using _Apply _LIBCPP_NODEBUG = typename _ITER_TRAITS<_Iter>::iterator_category; }; struct __iter_concept_random_fallback { template <class _Iter> - using _Apply = __enable_if_t< __is_primary_template<iterator_traits<_Iter> >::value, random_access_iterator_tag >; + using _Apply _LIBCPP_NODEBUG = + __enable_if_t<__is_primary_template<iterator_traits<_Iter> >::value, random_access_iterator_tag>; }; template <class _Iter, class _Tester> @@ -106,7 +107,7 @@ struct __iter_concept_cache { }; template <class _Iter> -using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>; +using _ITER_CONCEPT _LIBCPP_NODEBUG = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>; template <class _Tp> struct __has_iterator_typedefs { @@ -364,7 +365,7 @@ struct __iterator_traits<_Ip> { template <class _Ip> struct iterator_traits : __iterator_traits<_Ip> { - using __primary_template = iterator_traits; + using __primary_template _LIBCPP_NODEBUG = iterator_traits; }; #else // _LIBCPP_STD_VER >= 20 @@ -397,7 +398,7 @@ struct __iterator_traits<_Iter, true> template <class _Iter> struct _LIBCPP_TEMPLATE_VIS iterator_traits : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { - using __primary_template = iterator_traits; + using __primary_template _LIBCPP_NODEBUG = iterator_traits; }; #endif // _LIBCPP_STD_VER >= 20 @@ -430,16 +431,19 @@ template <class _Tp, class _Up> struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {}; template <class _Tp> -using __has_input_iterator_category = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>; +using __has_input_iterator_category _LIBCPP_NODEBUG = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>; template <class _Tp> -using __has_forward_iterator_category = __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>; +using __has_forward_iterator_category _LIBCPP_NODEBUG = + __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>; template <class _Tp> -using __has_bidirectional_iterator_category = __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>; +using __has_bidirectional_iterator_category _LIBCPP_NODEBUG = + __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>; template <class _Tp> -using __has_random_access_iterator_category = __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>; +using __has_random_access_iterator_category _LIBCPP_NODEBUG = + __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>; // __libcpp_is_contiguous_iterator determines if an iterator is known by // libc++ to be contiguous, either because it advertises itself as such @@ -466,48 +470,49 @@ template <class _Iter> class __wrap_iter; template <class _Tp> -using __has_exactly_input_iterator_category = +using __has_exactly_input_iterator_category _LIBCPP_NODEBUG = integral_constant<bool, __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value && !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>; template <class _Tp> -using __has_exactly_forward_iterator_category = +using __has_exactly_forward_iterator_category _LIBCPP_NODEBUG = integral_constant<bool, __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value && !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>; template <class _Tp> -using __has_exactly_bidirectional_iterator_category = +using __has_exactly_bidirectional_iterator_category _LIBCPP_NODEBUG = integral_constant<bool, __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value && !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>; template <class _InputIterator> -using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; +using __iter_value_type _LIBCPP_NODEBUG = typename iterator_traits<_InputIterator>::value_type; template <class _InputIterator> -using __iter_key_type = __remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>; +using __iter_key_type _LIBCPP_NODEBUG = + __remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>; template <class _InputIterator> -using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type; +using __iter_mapped_type _LIBCPP_NODEBUG = typename iterator_traits<_InputIterator>::value_type::second_type; template <class _InputIterator> -using __iter_to_alloc_type = +using __iter_to_alloc_type _LIBCPP_NODEBUG = pair<const typename iterator_traits<_InputIterator>::value_type::first_type, typename iterator_traits<_InputIterator>::value_type::second_type>; template <class _Iter> -using __iterator_category_type = typename iterator_traits<_Iter>::iterator_category; +using __iterator_category_type _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::iterator_category; template <class _Iter> -using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer; +using __iterator_pointer_type _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::pointer; template <class _Iter> -using __iter_diff_t = typename iterator_traits<_Iter>::difference_type; +using __iter_diff_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type; template <class _Iter> -using __iter_reference = typename iterator_traits<_Iter>::reference; +using __iter_reference _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::reference; #if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/projected.h b/libcxx/include/__iterator/projected.h index 1c560ec05500..d12f0167de1d 100644 --- a/libcxx/include/__iterator/projected.h +++ b/libcxx/include/__iterator/projected.h @@ -26,9 +26,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _It, class _Proj> struct __projected_impl { struct __type { - using __primary_template = __type; - using __projected_iterator = _It; - using __projected_projection = _Proj; + using __primary_template _LIBCPP_NODEBUG = __type; + using __projected_iterator _LIBCPP_NODEBUG = _It; + using __projected_projection _LIBCPP_NODEBUG = _Proj; using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>; indirect_result_t<_Proj&, _It> operator*() const; // not defined @@ -38,9 +38,9 @@ struct __projected_impl { template <weakly_incrementable _It, class _Proj> struct __projected_impl<_It, _Proj> { struct __type { - using __primary_template = __type; - using __projected_iterator = _It; - using __projected_projection = _Proj; + using __primary_template _LIBCPP_NODEBUG = __type; + using __projected_iterator _LIBCPP_NODEBUG = _It; + using __projected_projection _LIBCPP_NODEBUG = _Proj; using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>; using difference_type = iter_difference_t<_It>; diff --git a/libcxx/include/__iterator/ranges_iterator_traits.h b/libcxx/include/__iterator/ranges_iterator_traits.h index 859e7082048a..9a31b651eb5d 100644 --- a/libcxx/include/__iterator/ranges_iterator_traits.h +++ b/libcxx/include/__iterator/ranges_iterator_traits.h @@ -24,13 +24,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 template <ranges::input_range _Range> -using __range_key_type = __remove_const_t<typename ranges::range_value_t<_Range>::first_type>; +using __range_key_type _LIBCPP_NODEBUG = __remove_const_t<typename ranges::range_value_t<_Range>::first_type>; template <ranges::input_range _Range> -using __range_mapped_type = typename ranges::range_value_t<_Range>::second_type; +using __range_mapped_type _LIBCPP_NODEBUG = typename ranges::range_value_t<_Range>::second_type; template <ranges::input_range _Range> -using __range_to_alloc_type = +using __range_to_alloc_type _LIBCPP_NODEBUG = pair<const typename ranges::range_value_t<_Range>::first_type, typename ranges::range_value_t<_Range>::second_type>; #endif diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h index 5e88d86ad5e9..5bd1f868d3ff 100644 --- a/libcxx/include/__iterator/reverse_iterator.h +++ b/libcxx/include/__iterator/reverse_iterator.h @@ -329,8 +329,8 @@ __reverse_range(_Range&& __range) { template <class _Iter, bool __b> struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b> { - using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>())); - using _ReverseWrapper = reverse_iterator<reverse_iterator<_Iter> >; + using _UnwrappedIter _LIBCPP_NODEBUG = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>())); + using _ReverseWrapper _LIBCPP_NODEBUG = reverse_iterator<reverse_iterator<_Iter> >; static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper __rewrap(_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) { diff --git a/libcxx/include/__iterator/segmented_iterator.h b/libcxx/include/__iterator/segmented_iterator.h index 8cb54a35a7f5..7a8e1addeacd 100644 --- a/libcxx/include/__iterator/segmented_iterator.h +++ b/libcxx/include/__iterator/segmented_iterator.h @@ -72,7 +72,7 @@ template <class _Tp> struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {}; template <class _Iterator> -using __is_segmented_iterator = __has_specialization<__segmented_iterator_traits<_Iterator> >; +using __is_segmented_iterator _LIBCPP_NODEBUG = __has_specialization<__segmented_iterator_traits<_Iterator> >; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__locale b/libcxx/include/__locale index b675e01bac81..94dc8a08437b 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -50,7 +50,7 @@ _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&); class _LIBCPP_EXPORTED_FROM_ABI locale { public: // locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor. - using __trivially_relocatable = locale; + using __trivially_relocatable _LIBCPP_NODEBUG = locale; // types: class _LIBCPP_EXPORTED_FROM_ABI facet; diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h index c8097beb9052..9957429c1e7c 100644 --- a/libcxx/include/__locale_dir/locale_base_api.h +++ b/libcxx/include/__locale_dir/locale_base_api.h @@ -135,7 +135,7 @@ namespace __locale { // // Locale management // -using __locale_t = locale_t; +using __locale_t _LIBCPP_NODEBUG = locale_t; inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) { return newlocale(__category_mask, __name, __loc); diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h index edbc30a7a40e..65a697769bda 100644 --- a/libcxx/include/__mdspan/extents.h +++ b/libcxx/include/__mdspan/extents.h @@ -129,14 +129,14 @@ private: // Static values member static constexpr size_t __size_ = sizeof...(_Values); static constexpr size_t __size_dynamic_ = ((_Values == _DynTag) + ... + 0); - using _StaticValues = __static_array<_TStatic, _Values...>; - using _DynamicValues = __possibly_empty_array<_TDynamic, __size_dynamic_>; + using _StaticValues _LIBCPP_NODEBUG = __static_array<_TStatic, _Values...>; + using _DynamicValues _LIBCPP_NODEBUG = __possibly_empty_array<_TDynamic, __size_dynamic_>; // Dynamic values member _LIBCPP_NO_UNIQUE_ADDRESS _DynamicValues __dyn_vals_; // static mapping of indices to the position in the dynamic values array - using _DynamicIdxMap = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>; + using _DynamicIdxMap _LIBCPP_NODEBUG = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>; template <size_t... _Indices> _LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<_Indices...>) noexcept { @@ -292,7 +292,8 @@ private: static constexpr rank_type __rank_dynamic_ = ((_Extents == dynamic_extent) + ... + 0); // internal storage type using __maybe_static_array - using _Values = __mdspan_detail::__maybe_static_array<_IndexType, size_t, dynamic_extent, _Extents...>; + using _Values _LIBCPP_NODEBUG = + __mdspan_detail::__maybe_static_array<_IndexType, size_t, dynamic_extent, _Extents...>; [[no_unique_address]] _Values __vals_; public: diff --git a/libcxx/include/__memory/allocation_guard.h b/libcxx/include/__memory/allocation_guard.h index 66d6a5002c29..66edcd92ed61 100644 --- a/libcxx/include/__memory/allocation_guard.h +++ b/libcxx/include/__memory/allocation_guard.h @@ -45,8 +45,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // custom allocator. template <class _Alloc> struct __allocation_guard { - using _Pointer = typename allocator_traits<_Alloc>::pointer; - using _Size = typename allocator_traits<_Alloc>::size_type; + using _Pointer _LIBCPP_NODEBUG = typename allocator_traits<_Alloc>::pointer; + using _Size _LIBCPP_NODEBUG = typename allocator_traits<_Alloc>::size_type; template <class _AllocT> // we perform the allocator conversion inside the constructor _LIBCPP_HIDE_FROM_ABI explicit __allocation_guard(_AllocT __alloc, _Size __n) diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h index e35cfb7c3b87..afe3d1bf8a2d 100644 --- a/libcxx/include/__memory/pointer_traits.h +++ b/libcxx/include/__memory/pointer_traits.h @@ -176,10 +176,10 @@ public: #ifndef _LIBCPP_CXX03_LANG template <class _From, class _To> -using __rebind_pointer_t = typename pointer_traits<_From>::template rebind<_To>; +using __rebind_pointer_t _LIBCPP_NODEBUG = typename pointer_traits<_From>::template rebind<_To>; #else template <class _From, class _To> -using __rebind_pointer_t = typename pointer_traits<_From>::template rebind<_To>::other; +using __rebind_pointer_t _LIBCPP_NODEBUG = typename pointer_traits<_From>::template rebind<_To>::other; #endif // to_address @@ -276,7 +276,7 @@ struct __pointer_of<_Tp> { }; template <typename _Tp> -using __pointer_of_t = typename __pointer_of<_Tp>::type; +using __pointer_of_t _LIBCPP_NODEBUG = typename __pointer_of<_Tp>::type; template <class _Tp, class _Up> struct __pointer_of_or { @@ -290,7 +290,7 @@ struct __pointer_of_or<_Tp, _Up> { }; template <typename _Tp, typename _Up> -using __pointer_of_or_t = typename __pointer_of_or<_Tp, _Up>::type; +using __pointer_of_or_t _LIBCPP_NODEBUG = typename __pointer_of_or<_Tp, _Up>::type; template <class _Smart> concept __resettable_smart_pointer = requires(_Smart __s) { __s.reset(); }; diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h index 97e4031499ed..06b1fc488cf5 100644 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -141,7 +141,7 @@ struct __for_overwrite_tag {}; template <class _Tp, class _Alloc> struct __shared_ptr_emplace : __shared_weak_count { - using __value_type = __remove_cv_t<_Tp>; + using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>; template <class... _Args, class _Allocator = _Alloc, @@ -293,7 +293,8 @@ struct __shared_ptr_deleter_ctor_reqs { }; template <class _Dp> -using __shared_ptr_nullptr_deleter_ctor_reqs = _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >; +using __shared_ptr_nullptr_deleter_ctor_reqs _LIBCPP_NODEBUG = + _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >; #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI) # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__)) @@ -315,7 +316,7 @@ public: // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require // any bookkeeping, so it's always trivially relocatable. - using __trivially_relocatable = shared_ptr; + using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr; private: element_type* __ptr_; @@ -1210,7 +1211,7 @@ public: // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require // any bookkeeping, so it's always trivially relocatable. - using __trivially_relocatable = weak_ptr; + using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr; private: element_type* __ptr_; diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h index 2368f7b03e00..29d391fc80fe 100644 --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -153,7 +153,7 @@ public: // // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no // references to itself. This means that the entire structure is trivially relocatable if its members are. - using __trivially_relocatable = __conditional_t< + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t< __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, unique_ptr, void>; @@ -189,7 +189,7 @@ private: (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >; template <class _UDel> - using _EnableIfDeleterAssignable = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >; + using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = __enable_if_t< is_assignable<_Dp&, _UDel&&>::value >; public: template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > @@ -419,7 +419,7 @@ public: // // This unique_ptr implementation only contains a pointer to the unique object and a deleter, so there are no // references to itself. This means that the entire structure is trivially relocatable if its members are. - using __trivially_relocatable = __conditional_t< + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t< __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, unique_ptr, void>; @@ -430,9 +430,9 @@ private: _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_); #ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR - using _BoundsChecker = __unique_ptr_array_bounds_stored; + using _BoundsChecker _LIBCPP_NODEBUG = __unique_ptr_array_bounds_stored; #else - using _BoundsChecker = __unique_ptr_array_bounds_stateless; + using _BoundsChecker _LIBCPP_NODEBUG = __unique_ptr_array_bounds_stateless; #endif _LIBCPP_NO_UNIQUE_ADDRESS _BoundsChecker __checker_; diff --git a/libcxx/include/__memory/unique_temporary_buffer.h b/libcxx/include/__memory/unique_temporary_buffer.h index ca6292338c00..dea7fa8e1872 100644 --- a/libcxx/include/__memory/unique_temporary_buffer.h +++ b/libcxx/include/__memory/unique_temporary_buffer.h @@ -45,7 +45,7 @@ struct __temporary_buffer_deleter { }; template <class _Tp> -using __unique_temporary_buffer = unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> >; +using __unique_temporary_buffer _LIBCPP_NODEBUG = unique_ptr<_Tp, __temporary_buffer_deleter<_Tp> >; template <class _Tp> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_CONSTEXPR_SINCE_CXX23 __unique_temporary_buffer<_Tp> diff --git a/libcxx/include/__node_handle b/libcxx/include/__node_handle index d0b35bfd1934..8f32f2de8339 100644 --- a/libcxx/include/__node_handle +++ b/libcxx/include/__node_handle @@ -188,10 +188,10 @@ struct __map_node_handle_specifics { }; template <class _NodeType, class _Alloc> -using __set_node_handle = __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>; +using __set_node_handle _LIBCPP_NODEBUG = __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>; template <class _NodeType, class _Alloc> -using __map_node_handle = __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>; +using __map_node_handle _LIBCPP_NODEBUG = __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>; template <class _Iterator, class _NodeType> struct _LIBCPP_TEMPLATE_VIS __insert_return_type { diff --git a/libcxx/include/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h index cf4d26167aeb..97226476e5ef 100644 --- a/libcxx/include/__ostream/basic_ostream.h +++ b/libcxx/include/__ostream/basic_ostream.h @@ -88,6 +88,55 @@ public: return *this; } + template <class _Tp> + _LIBCPP_HIDE_FROM_ABI basic_ostream& __put_num(_Tp __value) { +# if _LIBCPP_HAS_EXCEPTIONS + try { +# endif // _LIBCPP_HAS_EXCEPTIONS + sentry __s(*this); + if (__s) { + using _Fp = num_put<char_type, ostreambuf_iterator<char_type, traits_type> >; + const _Fp& __facet = std::use_facet<_Fp>(this->getloc()); + if (__facet.put(*this, *this, this->fill(), __value).failed()) + this->setstate(ios_base::badbit | ios_base::failbit); + } +# if _LIBCPP_HAS_EXCEPTIONS + } catch (...) { + this->__set_badbit_and_consider_rethrow(); + } +# endif // _LIBCPP_HAS_EXCEPTIONS + return *this; + } + + template <class _Tp> + _LIBCPP_HIDE_FROM_ABI basic_ostream& __put_num_integer_promote(_Tp __value) { +# if _LIBCPP_HAS_EXCEPTIONS + try { +# endif // _LIBCPP_HAS_EXCEPTIONS + sentry __s(*this); + if (__s) { + ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield; + + using _Fp = num_put<char_type, ostreambuf_iterator<char_type, traits_type> >; + const _Fp& __facet = std::use_facet<_Fp>(this->getloc()); + if (__facet + .put(*this, + *this, + this->fill(), + __flags == ios_base::oct || __flags == ios_base::hex + ? static_cast<__copy_unsigned_t<_Tp, long> >(std::__to_unsigned_like(__value)) + : static_cast<__copy_unsigned_t<_Tp, long> >(__value)) + .failed()) + this->setstate(ios_base::badbit | ios_base::failbit); + } +# if _LIBCPP_HAS_EXCEPTIONS + } catch (...) { + this->__set_badbit_and_consider_rethrow(); + } +# endif // _LIBCPP_HAS_EXCEPTIONS + return *this; + } + basic_ostream& operator<<(bool __n); basic_ostream& operator<<(short __n); basic_ostream& operator<<(unsigned short __n); @@ -225,276 +274,67 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(bool __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(short __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield; - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, - *this, - this->fill(), - __flags == ios_base::oct || __flags == ios_base::hex - ? static_cast<long>(static_cast<unsigned short>(__n)) - : static_cast<long>(__n)) - .failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num_integer_promote(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num_integer_promote(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(int __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield; - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, - *this, - this->fill(), - __flags == ios_base::oct || __flags == ios_base::hex - ? static_cast<long>(static_cast<unsigned int>(__n)) - : static_cast<long>(__n)) - .failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num_integer_promote(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num_integer_promote(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long long __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(float __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), static_cast<double>(__n)).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return *this << static_cast<double>(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(double __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long double __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(const void* __n) { -# if _LIBCPP_HAS_EXCEPTIONS - try { -# endif // _LIBCPP_HAS_EXCEPTIONS - sentry __s(*this); - if (__s) { - typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp; - const _Fp& __f = std::use_facet<_Fp>(this->getloc()); - if (__f.put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit | ios_base::failbit); - } -# if _LIBCPP_HAS_EXCEPTIONS - } catch (...) { - this->__set_badbit_and_consider_rethrow(); - } -# endif // _LIBCPP_HAS_EXCEPTIONS - return *this; + return __put_num(__n); } template <class _CharT, class _Traits> diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h index 2132e8dbceb3..a7d53b6a1c98 100644 --- a/libcxx/include/__pstl/backend_fwd.h +++ b/libcxx/include/__pstl/backend_fwd.h @@ -53,11 +53,13 @@ struct __serial_backend_tag; struct __std_thread_backend_tag; # if defined(_LIBCPP_PSTL_BACKEND_SERIAL) -using __current_configuration = __backend_configuration<__serial_backend_tag, __default_backend_tag>; +using __current_configuration _LIBCPP_NODEBUG = __backend_configuration<__serial_backend_tag, __default_backend_tag>; # elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD) -using __current_configuration = __backend_configuration<__std_thread_backend_tag, __default_backend_tag>; +using __current_configuration _LIBCPP_NODEBUG = + __backend_configuration<__std_thread_backend_tag, __default_backend_tag>; # elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH) -using __current_configuration = __backend_configuration<__libdispatch_backend_tag, __default_backend_tag>; +using __current_configuration _LIBCPP_NODEBUG = + __backend_configuration<__libdispatch_backend_tag, __default_backend_tag>; # else // ...New vendors can add parallel backends here... diff --git a/libcxx/include/__pstl/dispatch.h b/libcxx/include/__pstl/dispatch.h index ea40fa79eb94..828842368e33 100644 --- a/libcxx/include/__pstl/dispatch.h +++ b/libcxx/include/__pstl/dispatch.h @@ -58,7 +58,8 @@ struct __find_first_implemented<_Algorithm, __backend_configuration<_B1, _Bn...> __find_first_implemented<_Algorithm, __backend_configuration<_Bn...>, _ExecutionPolicy> > {}; template <template <class, class> class _Algorithm, class _BackendConfiguration, class _ExecutionPolicy> -using __dispatch = typename __find_first_implemented<_Algorithm, _BackendConfiguration, _ExecutionPolicy>::type; +using __dispatch _LIBCPP_NODEBUG = + typename __find_first_implemented<_Algorithm, _BackendConfiguration, _ExecutionPolicy>::type; } // namespace __pstl _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__ranges/chunk_by_view.h b/libcxx/include/__ranges/chunk_by_view.h index e4df589bc286..71fee3a4f2d1 100644 --- a/libcxx/include/__ranges/chunk_by_view.h +++ b/libcxx/include/__ranges/chunk_by_view.h @@ -59,7 +59,7 @@ class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_by_view : public view_interface _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; // We cache the result of begin() to allow providing an amortized O(1). - using _Cache = __non_propagating_cache<iterator_t<_View>>; + using _Cache _LIBCPP_NODEBUG = __non_propagating_cache<iterator_t<_View>>; _Cache __cached_begin_; class __iterator; diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h index 87f66f17a2ab..3f963d04fff2 100644 --- a/libcxx/include/__ranges/drop_view.h +++ b/libcxx/include/__ranges/drop_view.h @@ -64,7 +64,7 @@ class drop_view : public view_interface<drop_view<_View>> { // Note: drop_view<input-range>::begin() is still trivially amortized O(1) because // one can't call begin() on it more than once. static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>); - using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + using _Cache _LIBCPP_NODEBUG = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); range_difference_t<_View> __count_ = 0; _View __base_ = _View(); @@ -204,7 +204,7 @@ struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> { }; template <class _Tp> -using __passthrough_type_t = typename __passthrough_type<_Tp>::type; +using __passthrough_type_t _LIBCPP_NODEBUG = typename __passthrough_type<_Tp>::type; struct __fn { // [range.drop.overview]: the `empty_view` case. diff --git a/libcxx/include/__ranges/drop_while_view.h b/libcxx/include/__ranges/drop_while_view.h index 6413ff52bc0e..bc7f019393a8 100644 --- a/libcxx/include/__ranges/drop_while_view.h +++ b/libcxx/include/__ranges/drop_while_view.h @@ -90,7 +90,7 @@ private: _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; static constexpr bool _UseCache = forward_range<_View>; - using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + using _Cache _LIBCPP_NODEBUG = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); }; diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h index c99282f37960..5121298fb684 100644 --- a/libcxx/include/__ranges/elements_view.h +++ b/libcxx/include/__ranges/elements_view.h @@ -171,7 +171,7 @@ class elements_view<_View, _Np>::__iterator template <bool> friend class __sentinel; - using _Base = __maybe_const<_Const, _View>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; iterator_t<_Base> __current_ = iterator_t<_Base>(); @@ -335,7 +335,7 @@ template <input_range _View, size_t _Np> template <bool _Const> class elements_view<_View, _Np>::__sentinel { private: - using _Base = __maybe_const<_Const, _View>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); template <bool> diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h index 22f67b2d967d..07980e735319 100644 --- a/libcxx/include/__ranges/filter_view.h +++ b/libcxx/include/__ranges/filter_view.h @@ -61,7 +61,7 @@ class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS filter_view : public view_interface<f // We cache the result of begin() to allow providing an amortized O(1) begin() whenever // the underlying range is at least a forward_range. static constexpr bool _UseCache = forward_range<_View>; - using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + using _Cache _LIBCPP_NODEBUG = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); class __iterator; @@ -115,7 +115,7 @@ struct __filter_iterator_category {}; template <forward_range _View> struct __filter_iterator_category<_View> { - using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category; + using _Cat _LIBCPP_NODEBUG = typename iterator_traits<iterator_t<_View>>::iterator_category; using iterator_category = _If<derived_from<_Cat, bidirectional_iterator_tag>, bidirectional_iterator_tag, diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h index b2fa958a0f56..4b84585258b9 100644 --- a/libcxx/include/__ranges/iota_view.h +++ b/libcxx/include/__ranges/iota_view.h @@ -68,7 +68,7 @@ struct __get_wider_signed { }; template <class _Start> -using _IotaDiffT = +using _IotaDiffT _LIBCPP_NODEBUG = typename _If< (!integral<_Start> || sizeof(iter_difference_t<_Start>) > sizeof(_Start)), type_identity<iter_difference_t<_Start>>, __get_wider_signed<_Start> >::type; diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h index 6aadd387860e..327b349f476a 100644 --- a/libcxx/include/__ranges/join_view.h +++ b/libcxx/include/__ranges/join_view.h @@ -55,8 +55,8 @@ struct __join_view_iterator_category {}; template <class _View> requires is_reference_v<range_reference_t<_View>> && forward_range<_View> && forward_range<range_reference_t<_View>> struct __join_view_iterator_category<_View> { - using _OuterC = typename iterator_traits<iterator_t<_View>>::iterator_category; - using _InnerC = typename iterator_traits<iterator_t<range_reference_t<_View>>>::iterator_category; + using _OuterC _LIBCPP_NODEBUG = typename iterator_traits<iterator_t<_View>>::iterator_category; + using _InnerC _LIBCPP_NODEBUG = typename iterator_traits<iterator_t<range_reference_t<_View>>>::iterator_category; using iterator_category = _If< derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag> && @@ -71,7 +71,7 @@ template <input_range _View> requires view<_View> && input_range<range_reference_t<_View>> class join_view : public view_interface<join_view<_View>> { private: - using _InnerRange = range_reference_t<_View>; + using _InnerRange _LIBCPP_NODEBUG = range_reference_t<_View>; template <bool> struct __iterator; @@ -85,11 +85,12 @@ private: _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); static constexpr bool _UseOuterCache = !forward_range<_View>; - using _OuterCache = _If<_UseOuterCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + using _OuterCache _LIBCPP_NODEBUG = _If<_UseOuterCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _OuterCache __outer_; static constexpr bool _UseInnerCache = !is_reference_v<_InnerRange>; - using _InnerCache = _If<_UseInnerCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>; + using _InnerCache _LIBCPP_NODEBUG = + _If<_UseInnerCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _InnerCache __inner_; public: @@ -155,9 +156,9 @@ private: template <bool> friend struct __sentinel; - using _Parent = __maybe_const<_Const, join_view>; - using _Base = __maybe_const<_Const, _View>; - sentinel_t<_Base> __end_ = sentinel_t<_Base>(); + using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, join_view>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; + sentinel_t<_Base> __end_ = sentinel_t<_Base>(); public: _LIBCPP_HIDE_FROM_ABI __sentinel() = default; @@ -190,18 +191,18 @@ struct join_view<_View>::__iterator final : public __join_view_iterator_category static constexpr bool __is_join_view_iterator = true; private: - using _Parent = __maybe_const<_Const, join_view<_View>>; - using _Base = __maybe_const<_Const, _View>; - using _Outer = iterator_t<_Base>; - using _Inner = iterator_t<range_reference_t<_Base>>; - using _InnerRange = range_reference_t<_View>; + using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, join_view<_View>>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; + using _Outer _LIBCPP_NODEBUG = iterator_t<_Base>; + using _Inner _LIBCPP_NODEBUG = iterator_t<range_reference_t<_Base>>; + using _InnerRange _LIBCPP_NODEBUG = range_reference_t<_View>; static_assert(!_Const || forward_range<_Base>, "Const can only be true when Base models forward_range."); static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>; static constexpr bool _OuterPresent = forward_range<_Base>; - using _OuterType = _If<_OuterPresent, _Outer, std::__empty>; + using _OuterType _LIBCPP_NODEBUG = _If<_OuterPresent, _Outer, std::__empty>; _LIBCPP_NO_UNIQUE_ADDRESS _OuterType __outer_ = _OuterType(); optional<_Inner> __inner_; @@ -379,7 +380,7 @@ template <class _JoinViewIterator> struct __segmented_iterator_traits<_JoinViewIterator> { using __segment_iterator _LIBCPP_NODEBUG = __iterator_with_data<typename _JoinViewIterator::_Outer, typename _JoinViewIterator::_Parent*>; - using __local_iterator = typename _JoinViewIterator::_Inner; + using __local_iterator _LIBCPP_NODEBUG = typename _JoinViewIterator::_Inner; // TODO: Would it make sense to enable the optimization for other iterator types? diff --git a/libcxx/include/__ranges/lazy_split_view.h b/libcxx/include/__ranges/lazy_split_view.h index 0dcbc134a21f..cca9191d2681 100644 --- a/libcxx/include/__ranges/lazy_split_view.h +++ b/libcxx/include/__ranges/lazy_split_view.h @@ -72,7 +72,8 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>> _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern(); - using _MaybeCurrent = _If<!forward_range<_View>, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + using _MaybeCurrent _LIBCPP_NODEBUG = + _If<!forward_range<_View>, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent(); template <bool> @@ -146,11 +147,11 @@ private: friend struct __inner_iterator; friend __outer_iterator<true>; - using _Parent = __maybe_const<_Const, lazy_split_view>; - using _Base = __maybe_const<_Const, _View>; + using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, lazy_split_view>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; _Parent* __parent_ = nullptr; - using _MaybeCurrent = _If<forward_range<_View>, iterator_t<_Base>, __empty_cache>; + using _MaybeCurrent _LIBCPP_NODEBUG = _If<forward_range<_View>, iterator_t<_Base>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent(); bool __trailing_empty_ = false; @@ -283,7 +284,7 @@ private: template <bool _Const> struct __inner_iterator : __inner_iterator_category<__maybe_const<_Const, _View>> { private: - using _Base = __maybe_const<_Const, _View>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; // Workaround for a GCC issue. static constexpr bool _OuterConst = _Const; __outer_iterator<_Const> __i_ = __outer_iterator<_OuterConst>(); diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index 93ceaf1711d3..61a8b6357105 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -61,7 +61,7 @@ struct __repeat_view_iterator_difference<_Tp> { }; template <class _Tp> -using __repeat_view_iterator_difference_t = typename __repeat_view_iterator_difference<_Tp>::type; +using __repeat_view_iterator_difference_t _LIBCPP_NODEBUG = typename __repeat_view_iterator_difference<_Tp>::type; namespace views::__drop { struct __fn; @@ -139,7 +139,7 @@ template <move_constructible _Tp, semiregular _Bound> class repeat_view<_Tp, _Bound>::__iterator { friend class repeat_view; - using _IndexT = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>; + using _IndexT _LIBCPP_NODEBUG = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>; _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(const _Tp* __value, _IndexT __bound_sentinel = _IndexT()) : __value_(__value), __current_(__bound_sentinel) {} diff --git a/libcxx/include/__ranges/reverse_view.h b/libcxx/include/__ranges/reverse_view.h index 796f5be22328..80d54b9a6c83 100644 --- a/libcxx/include/__ranges/reverse_view.h +++ b/libcxx/include/__ranges/reverse_view.h @@ -47,7 +47,8 @@ class reverse_view : public view_interface<reverse_view<_View>> { // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an // amortized O(1) begin() method. static constexpr bool _UseCache = !random_access_range<_View> && !common_range<_View>; - using _Cache = _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>; + using _Cache _LIBCPP_NODEBUG = + _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>; _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache(); _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); diff --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h index 7527281905ff..2ec908ba4070 100644 --- a/libcxx/include/__ranges/split_view.h +++ b/libcxx/include/__ranges/split_view.h @@ -52,7 +52,7 @@ class split_view : public view_interface<split_view<_View, _Pattern>> { private: _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern(); - using _Cache = __non_propagating_cache<subrange<iterator_t<_View>>>; + using _Cache _LIBCPP_NODEBUG = __non_propagating_cache<subrange<iterator_t<_View>>>; _Cache __cached_begin_ = _Cache(); template <class, class> diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h index a40eab3c5a25..2d006d3570a7 100644 --- a/libcxx/include/__ranges/subrange.h +++ b/libcxx/include/__ranges/subrange.h @@ -82,7 +82,7 @@ private: struct _Empty { _LIBCPP_HIDE_FROM_ABI constexpr _Empty(auto) noexcept {} }; - using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>; + using _Size _LIBCPP_NODEBUG = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>; _LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter(); _LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent(); _LIBCPP_NO_UNIQUE_ADDRESS _Size __size_ = 0; diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h index 39f99cee6b4d..5892c1e31fae 100644 --- a/libcxx/include/__ranges/take_view.h +++ b/libcxx/include/__ranges/take_view.h @@ -161,9 +161,9 @@ public: template <view _View> template <bool _Const> class take_view<_View>::__sentinel { - using _Base = __maybe_const<_Const, _View>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; template <bool _OtherConst> - using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; + using _Iter _LIBCPP_NODEBUG = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); template <bool> @@ -244,7 +244,7 @@ struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> { }; template <class _Tp> -using __passthrough_type_t = typename __passthrough_type<_Tp>::type; +using __passthrough_type_t _LIBCPP_NODEBUG = typename __passthrough_type<_Tp>::type; struct __fn { // [range.take.overview]: the `empty_view` case. diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h index b7cb0aef58f1..4977f139fc55 100644 --- a/libcxx/include/__ranges/take_while_view.h +++ b/libcxx/include/__ranges/take_while_view.h @@ -103,7 +103,7 @@ template <view _View, class _Pred> requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>> template <bool _Const> class take_while_view<_View, _Pred>::__sentinel { - using _Base = __maybe_const<_Const, _View>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; sentinel_t<_Base> __end_ = sentinel_t<_Base>(); const _Pred* __pred_ = nullptr; diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h index 0ce1bfe88350..4ae21e92b69d 100644 --- a/libcxx/include/__ranges/transform_view.h +++ b/libcxx/include/__ranges/transform_view.h @@ -159,7 +159,7 @@ struct __transform_view_iterator_category_base {}; template <forward_range _View, class _Fn> struct __transform_view_iterator_category_base<_View, _Fn> { - using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category; + using _Cat _LIBCPP_NODEBUG = typename iterator_traits<iterator_t<_View>>::iterator_category; using iterator_category = conditional_t< is_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>, @@ -177,8 +177,8 @@ template <bool _Const> class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, __maybe_const<_Const, _Fn>> { - using _Parent = __maybe_const<_Const, transform_view>; - using _Base = __maybe_const<_Const, _View>; + using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, transform_view>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; _Parent* __parent_ = nullptr; @@ -338,8 +338,8 @@ template <input_range _View, copy_constructible _Fn> requires __transform_view_constraints<_View, _Fn> template <bool _Const> class transform_view<_View, _Fn>::__sentinel { - using _Parent = __maybe_const<_Const, transform_view>; - using _Base = __maybe_const<_Const, _View>; + using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, transform_view>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; sentinel_t<_Base> __end_ = sentinel_t<_Base>(); diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer index 9d7fd3e0df62..a8f679cc30a9 100644 --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -51,24 +51,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp, class _Allocator = allocator<_Tp> > struct __split_buffer { public: - using value_type = _Tp; - using allocator_type = _Allocator; - using __alloc_rr = __libcpp_remove_reference_t<allocator_type>; - using __alloc_traits = allocator_traits<__alloc_rr>; - using reference = value_type&; - using const_reference = const value_type&; - using size_type = typename __alloc_traits::size_type; - using difference_type = typename __alloc_traits::difference_type; - using pointer = typename __alloc_traits::pointer; - using const_pointer = typename __alloc_traits::const_pointer; - using iterator = pointer; - using const_iterator = const_pointer; + using value_type = _Tp; + using allocator_type = _Allocator; + using __alloc_rr _LIBCPP_NODEBUG = __libcpp_remove_reference_t<allocator_type>; + using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<__alloc_rr>; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = typename __alloc_traits::size_type; + using difference_type = typename __alloc_traits::difference_type; + using pointer = typename __alloc_traits::pointer; + using const_pointer = typename __alloc_traits::const_pointer; + using iterator = pointer; + using const_iterator = const_pointer; // A __split_buffer contains the following members which may be trivially relocatable: // - pointer: may be trivially relocatable, so it's checked // - allocator_type: may be trivially relocatable, so it's checked // __split_buffer doesn't have any self-references, so it's trivially relocatable if its members are. - using __trivially_relocatable = __conditional_t< + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t< __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, __split_buffer, void>; diff --git a/libcxx/include/__stop_token/stop_state.h b/libcxx/include/__stop_token/stop_state.h index 84dc208dda36..cc1f1d830e8d 100644 --- a/libcxx/include/__stop_token/stop_state.h +++ b/libcxx/include/__stop_token/stop_state.h @@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_THREADS struct __stop_callback_base : __intrusive_node_base<__stop_callback_base> { - using __callback_fn_t = void(__stop_callback_base*) noexcept; + using __callback_fn_t _LIBCPP_NODEBUG = void(__stop_callback_base*) noexcept; _LIBCPP_HIDE_FROM_ABI explicit __stop_callback_base(__callback_fn_t* __callback_fn) : __callback_fn_(__callback_fn) {} _LIBCPP_HIDE_FROM_ABI void __invoke() noexcept { __callback_fn_(this); } @@ -58,9 +58,9 @@ class __stop_state { // It is used by __intrusive_shared_ptr, but it is stored here for better layout atomic<uint32_t> __ref_count_ = 0; - using __state_t = uint32_t; - using __callback_list_lock = __atomic_unique_lock<__state_t, __callback_list_locked_bit>; - using __callback_list = __intrusive_list_view<__stop_callback_base>; + using __state_t _LIBCPP_NODEBUG = uint32_t; + using __callback_list_lock _LIBCPP_NODEBUG = __atomic_unique_lock<__state_t, __callback_list_locked_bit>; + using __callback_list _LIBCPP_NODEBUG = __intrusive_list_view<__stop_callback_base>; __callback_list __callback_list_; __thread_id __requesting_thread_; diff --git a/libcxx/include/__system_error/system_error.h b/libcxx/include/__system_error/system_error.h index 918effb6917c..36ccf94cc010 100644 --- a/libcxx/include/__system_error/system_error.h +++ b/libcxx/include/__system_error/system_error.h @@ -39,6 +39,10 @@ public: _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; } }; +// __ev is expected to be an error in the generic_category domain (e.g. from +// errno, or std::errc::*), not system_category (e.g. from windows syscalls). +[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void __throw_system_error(int __ev, const char* __what_arg); + [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI inline void __throw_system_error(error_code __ec, const char* __what_arg) { #if _LIBCPP_HAS_EXCEPTIONS throw system_error(__ec, __what_arg); diff --git a/libcxx/include/__thread/support/pthread.h b/libcxx/include/__thread/support/pthread.h index 531f3e71de83..14e92079dadf 100644 --- a/libcxx/include/__thread/support/pthread.h +++ b/libcxx/include/__thread/support/pthread.h @@ -39,7 +39,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -using __libcpp_timespec_t = ::timespec; +using __libcpp_timespec_t _LIBCPP_NODEBUG = ::timespec; // // Mutex diff --git a/libcxx/include/__tuple/make_tuple_types.h b/libcxx/include/__tuple/make_tuple_types.h index 3d312395131d..ff95ca4313a5 100644 --- a/libcxx/include/__tuple/make_tuple_types.h +++ b/libcxx/include/__tuple/make_tuple_types.h @@ -47,9 +47,9 @@ struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> { template <class _Vt, size_t _Np, size_t... _Idx> struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> { template <size_t> - using __value_type = _Vt; + using __value_type _LIBCPP_NODEBUG = _Vt; template <class _Tp> - using __apply_quals = __tuple_types<__copy_cvref_t<_Tp, __value_type<_Idx>>...>; + using __apply_quals _LIBCPP_NODEBUG = __tuple_types<__copy_cvref_t<_Tp, __value_type<_Idx>>...>; }; template <class _Tp, @@ -58,9 +58,9 @@ template <class _Tp, bool _SameSize = (_Ep == tuple_size<__libcpp_remove_reference_t<_Tp> >::value)> struct __make_tuple_types { static_assert(_Sp <= _Ep, "__make_tuple_types input error"); - using _RawTp = __remove_cvref_t<_Tp>; - using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; - using type = typename _Maker::template __apply_quals<_Tp>; + using _RawTp _LIBCPP_NODEBUG = __remove_cvref_t<_Tp>; + using _Maker _LIBCPP_NODEBUG = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; + using type = typename _Maker::template __apply_quals<_Tp>; }; template <class... _Types, size_t _Ep> diff --git a/libcxx/include/__tuple/sfinae_helpers.h b/libcxx/include/__tuple/sfinae_helpers.h index 9041d1d4473e..4084e8bb31fd 100644 --- a/libcxx/include/__tuple/sfinae_helpers.h +++ b/libcxx/include/__tuple/sfinae_helpers.h @@ -41,7 +41,7 @@ struct __tuple_sfinae_base { static auto __do_test(...) -> false_type; template <class _FromArgs, class _ToArgs> - using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); + using __constructible _LIBCPP_NODEBUG = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); }; // __tuple_constructible diff --git a/libcxx/include/__tuple/tuple_size.h b/libcxx/include/__tuple/tuple_size.h index b970280fe378..27d57eb56ba6 100644 --- a/libcxx/include/__tuple/tuple_size.h +++ b/libcxx/include/__tuple/tuple_size.h @@ -29,7 +29,7 @@ struct _LIBCPP_TEMPLATE_VIS tuple_size; #if !defined(_LIBCPP_CXX03_LANG) template <class _Tp, class...> -using __enable_if_tuple_size_imp = _Tp; +using __enable_if_tuple_size_imp _LIBCPP_NODEBUG = _Tp; template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< const _Tp, diff --git a/libcxx/include/__type_traits/add_lvalue_reference.h b/libcxx/include/__type_traits/add_lvalue_reference.h index 157c8f94d476..b1ee6ed73c8a 100644 --- a/libcxx/include/__type_traits/add_lvalue_reference.h +++ b/libcxx/include/__type_traits/add_lvalue_reference.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if __has_builtin(__add_lvalue_reference) template <class _Tp> -using __add_lvalue_reference_t = __add_lvalue_reference(_Tp); +using __add_lvalue_reference_t _LIBCPP_NODEBUG = __add_lvalue_reference(_Tp); #else diff --git a/libcxx/include/__type_traits/add_pointer.h b/libcxx/include/__type_traits/add_pointer.h index f66e1f9e6c06..b53d8eae708e 100644 --- a/libcxx/include/__type_traits/add_pointer.h +++ b/libcxx/include/__type_traits/add_pointer.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) template <class _Tp> -using __add_pointer_t = __add_pointer(_Tp); +using __add_pointer_t _LIBCPP_NODEBUG = __add_pointer(_Tp); #else template <class _Tp, bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value> diff --git a/libcxx/include/__type_traits/add_rvalue_reference.h b/libcxx/include/__type_traits/add_rvalue_reference.h index 205058892c87..d844ccc1f539 100644 --- a/libcxx/include/__type_traits/add_rvalue_reference.h +++ b/libcxx/include/__type_traits/add_rvalue_reference.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if __has_builtin(__add_rvalue_reference) template <class _Tp> -using __add_rvalue_reference_t = __add_rvalue_reference(_Tp); +using __add_rvalue_reference_t _LIBCPP_NODEBUG = __add_rvalue_reference(_Tp); #else diff --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h index 2e39afb7f880..d98749980122 100644 --- a/libcxx/include/__type_traits/aligned_storage.h +++ b/libcxx/include/__type_traits/aligned_storage.h @@ -34,26 +34,23 @@ struct __struct_double4 { double __lx[4]; }; -// clang-format off -typedef __type_list<__align_type<unsigned char>, - __type_list<__align_type<unsigned short>, - __type_list<__align_type<unsigned int>, - __type_list<__align_type<unsigned long>, - __type_list<__align_type<unsigned long long>, - __type_list<__align_type<double>, - __type_list<__align_type<long double>, - __type_list<__align_type<__struct_double>, - __type_list<__align_type<__struct_double4>, - __type_list<__align_type<int*>, - __nat - > > > > > > > > > > __all_types; -// clang-format on +using __all_types _LIBCPP_NODEBUG = + __type_list<__align_type<unsigned char>, + __align_type<unsigned short>, + __align_type<unsigned int>, + __align_type<unsigned long>, + __align_type<unsigned long long>, + __align_type<double>, + __align_type<long double>, + __align_type<__struct_double>, + __align_type<__struct_double4>, + __align_type<int*> >; template <class _TL, size_t _Len> struct __find_max_align; -template <class _Hp, size_t _Len> -struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {}; +template <class _Head, size_t _Len> +struct __find_max_align<__type_list<_Head>, _Len> : public integral_constant<size_t, _Head::value> {}; template <size_t _Len, size_t _A1, size_t _A2> struct __select_align { @@ -65,9 +62,11 @@ public: static const size_t value = _Len < __max ? __min : __max; }; -template <class _Hp, class _Tp, size_t _Len> -struct __find_max_align<__type_list<_Hp, _Tp>, _Len> - : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {}; +template <class _Head, class... _Tail, size_t _Len> +struct __find_max_align<__type_list<_Head, _Tail...>, _Len> + : public integral_constant< + size_t, + __select_align<_Len, _Head::value, __find_max_align<__type_list<_Tail...>, _Len>::value>::value> {}; template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage { diff --git a/libcxx/include/__type_traits/common_reference.h b/libcxx/include/__type_traits/common_reference.h index c802902eb19f..d436949e692f 100644 --- a/libcxx/include/__type_traits/common_reference.h +++ b/libcxx/include/__type_traits/common_reference.h @@ -30,7 +30,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // Let COND_RES(X, Y) be: template <class _Xp, class _Yp> -using __cond_res = decltype(false ? std::declval<_Xp (&)()>()() : std::declval<_Yp (&)()>()()); +using __cond_res _LIBCPP_NODEBUG = decltype(false ? std::declval<_Xp (&)()>()() : std::declval<_Yp (&)()>()()); // Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U` // with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type @@ -39,7 +39,7 @@ using __cond_res = decltype(false ? std::declval<_Xp (&)()>()() : std::declval<_ template <class _Tp> struct __xref { template <class _Up> - using __apply = __copy_cvref_t<_Tp, _Up>; + using __apply _LIBCPP_NODEBUG = __copy_cvref_t<_Tp, _Up>; }; // Given types A and B, let X be remove_reference_t<A>, let Y be remove_reference_t<B>, @@ -48,10 +48,10 @@ template <class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = struct __common_ref; template <class _Xp, class _Yp> -using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type; +using __common_ref_t _LIBCPP_NODEBUG = typename __common_ref<_Xp, _Yp>::__type; template <class _Xp, class _Yp> -using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>; +using __cv_cond_res _LIBCPP_NODEBUG = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>; // If A and B are both lvalue reference types, COMMON-REF(A, B) is // COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type. @@ -61,13 +61,13 @@ template <class _Ap, class _Bp, class _Xp, class _Yp> requires { typename __cv_cond_res<_Xp, _Yp>; } && is_reference_v<__cv_cond_res<_Xp, _Yp>> struct __common_ref<_Ap&, _Bp&, _Xp, _Yp> { - using __type = __cv_cond_res<_Xp, _Yp>; + using __type _LIBCPP_NODEBUG = __cv_cond_res<_Xp, _Yp>; }; // clang-format on // Otherwise, let C be remove_reference_t<COMMON-REF(X&, Y&)>&&. ... template <class _Xp, class _Yp> -using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&; +using __common_ref_C _LIBCPP_NODEBUG = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&; // .... If A and B are both rvalue reference types, C is well-formed, and // is_convertible_v<A, C> && is_convertible_v<B, C> is true, then COMMON-REF(A, B) is C. @@ -78,13 +78,13 @@ template <class _Ap, class _Bp, class _Xp, class _Yp> is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> && is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>> struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp> { - using __type = __common_ref_C<_Xp, _Yp>; + using __type _LIBCPP_NODEBUG = __common_ref_C<_Xp, _Yp>; }; // clang-format on // Otherwise, let D be COMMON-REF(const X&, Y&). ... template <class _Tp, class _Up> -using __common_ref_D = __common_ref_t<const _Tp&, _Up&>; +using __common_ref_D _LIBCPP_NODEBUG = __common_ref_t<const _Tp&, _Up&>; // ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and // is_convertible_v<A, D> is true, then COMMON-REF(A, B) is D. @@ -94,7 +94,7 @@ template <class _Ap, class _Bp, class _Xp, class _Yp> requires { typename __common_ref_D<_Xp, _Yp>; } && is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>> struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp> { - using __type = __common_ref_D<_Xp, _Yp>; + using __type _LIBCPP_NODEBUG = __common_ref_D<_Xp, _Yp>; }; // clang-format on @@ -150,7 +150,7 @@ template <class, class, template <class> class, template <class> class> struct basic_common_reference {}; template <class _Tp, class _Up> -using __basic_common_reference_t = +using __basic_common_reference_t _LIBCPP_NODEBUG = typename basic_common_reference<remove_cvref_t<_Tp>, remove_cvref_t<_Up>, __xref<_Tp>::template __apply, diff --git a/libcxx/include/__type_traits/common_type.h b/libcxx/include/__type_traits/common_type.h index ee5596bd1249..e4c6b495c3bd 100644 --- a/libcxx/include/__type_traits/common_type.h +++ b/libcxx/include/__type_traits/common_type.h @@ -31,7 +31,7 @@ template <class... _Args> struct common_type; template <class... _Args> -using __common_type_t = typename common_type<_Args...>::type; +using __common_type_t _LIBCPP_NODEBUG = typename common_type<_Args...>::type; template <class... _Args> struct common_type : __builtin_common_type<__common_type_t, __type_identity, __empty, _Args...> {}; @@ -40,7 +40,7 @@ struct common_type : __builtin_common_type<__common_type_t, __type_identity, __e # if _LIBCPP_STD_VER >= 20 // Let COND_RES(X, Y) be: template <class _Tp, class _Up> -using __cond_type = decltype(false ? std::declval<_Tp>() : std::declval<_Up>()); +using __cond_type _LIBCPP_NODEBUG = decltype(false ? std::declval<_Tp>() : std::declval<_Up>()); template <class _Tp, class _Up, class = void> struct __common_type3 {}; diff --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h index c2995591bbc2..4001d6c12d5d 100644 --- a/libcxx/include/__type_traits/conjunction.h +++ b/libcxx/include/__type_traits/conjunction.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class...> -using __expand_to_true = true_type; +using __expand_to_true _LIBCPP_NODEBUG = true_type; template <class... _Pred> __expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int); diff --git a/libcxx/include/__type_traits/copy_cv.h b/libcxx/include/__type_traits/copy_cv.h index d482cb42bffe..8378fbd50ef5 100644 --- a/libcxx/include/__type_traits/copy_cv.h +++ b/libcxx/include/__type_traits/copy_cv.h @@ -22,29 +22,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _From> struct __copy_cv { template <class _To> - using __apply = _To; + using __apply _LIBCPP_NODEBUG = _To; }; template <class _From> struct __copy_cv<const _From> { template <class _To> - using __apply = const _To; + using __apply _LIBCPP_NODEBUG = const _To; }; template <class _From> struct __copy_cv<volatile _From> { template <class _To> - using __apply = volatile _To; + using __apply _LIBCPP_NODEBUG = volatile _To; }; template <class _From> struct __copy_cv<const volatile _From> { template <class _To> - using __apply = const volatile _To; + using __apply _LIBCPP_NODEBUG = const volatile _To; }; template <class _From, class _To> -using __copy_cv_t = typename __copy_cv<_From>::template __apply<_To>; +using __copy_cv_t _LIBCPP_NODEBUG = typename __copy_cv<_From>::template __apply<_To>; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/copy_cvref.h b/libcxx/include/__type_traits/copy_cvref.h index 8bbf8efdf44d..511d4e0776d6 100644 --- a/libcxx/include/__type_traits/copy_cvref.h +++ b/libcxx/include/__type_traits/copy_cvref.h @@ -36,7 +36,7 @@ struct __copy_cvref<_From&&, _To> { }; template <class _From, class _To> -using __copy_cvref_t = typename __copy_cvref<_From, _To>::type; +using __copy_cvref_t _LIBCPP_NODEBUG = typename __copy_cvref<_From, _To>::type; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/disjunction.h b/libcxx/include/__type_traits/disjunction.h index 2c89528d9f2f..d579de9b9843 100644 --- a/libcxx/include/__type_traits/disjunction.h +++ b/libcxx/include/__type_traits/disjunction.h @@ -31,7 +31,7 @@ struct _OrImpl<true> { template <> struct _OrImpl<false> { template <class _Res, class...> - using _Result = _Res; + using _Result _LIBCPP_NODEBUG = _Res; }; // _Or always performs lazy evaluation of its arguments. diff --git a/libcxx/include/__type_traits/invoke.h b/libcxx/include/__type_traits/invoke.h index 71db32ae6a3c..6f641b9a81b8 100644 --- a/libcxx/include/__type_traits/invoke.h +++ b/libcxx/include/__type_traits/invoke.h @@ -44,12 +44,12 @@ template <class _Fp, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0>, class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> -using __enable_if_bullet1 = +using __enable_if_bullet1 _LIBCPP_NODEBUG = __enable_if_t<is_member_function_pointer<_DecayFp>::value && (is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value)>; template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> > -using __enable_if_bullet2 = +using __enable_if_bullet2 _LIBCPP_NODEBUG = __enable_if_t<is_member_function_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value>; template <class _Fp, @@ -57,7 +57,7 @@ template <class _Fp, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0>, class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> -using __enable_if_bullet3 = +using __enable_if_bullet3 _LIBCPP_NODEBUG = __enable_if_t<is_member_function_pointer<_DecayFp>::value && !(is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value) && !__is_reference_wrapper<_DecayA0>::value>; @@ -67,12 +67,12 @@ template <class _Fp, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0>, class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> -using __enable_if_bullet4 = +using __enable_if_bullet4 _LIBCPP_NODEBUG = __enable_if_t<is_member_object_pointer<_DecayFp>::value && (is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value)>; template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> > -using __enable_if_bullet5 = +using __enable_if_bullet5 _LIBCPP_NODEBUG = __enable_if_t<is_member_object_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value>; template <class _Fp, @@ -80,7 +80,7 @@ template <class _Fp, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0>, class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> -using __enable_if_bullet6 = +using __enable_if_bullet6 _LIBCPP_NODEBUG = __enable_if_t<is_member_object_pointer<_DecayFp>::value && !(is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value) && !__is_reference_wrapper<_DecayA0>::value>; @@ -159,7 +159,7 @@ struct __invokable_r { // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, // or incomplete array types as required by the standard. - using _Result = decltype(__try_call<_Fp, _Args...>(0)); + using _Result _LIBCPP_NODEBUG = decltype(__try_call<_Fp, _Args...>(0)); using type = __conditional_t<_IsNotSame<_Result, __nat>::value, __conditional_t<is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >, @@ -167,7 +167,7 @@ struct __invokable_r { static const bool value = type::value; }; template <class _Fp, class... _Args> -using __invokable = __invokable_r<void, _Fp, _Args...>; +using __invokable _LIBCPP_NODEBUG = __invokable_r<void, _Fp, _Args...>; template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class... _Args> struct __nothrow_invokable_r_imp { @@ -199,11 +199,12 @@ struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> { }; template <class _Ret, class _Fp, class... _Args> -using __nothrow_invokable_r = +using __nothrow_invokable_r _LIBCPP_NODEBUG = __nothrow_invokable_r_imp<__invokable_r<_Ret, _Fp, _Args...>::value, is_void<_Ret>::value, _Ret, _Fp, _Args...>; template <class _Fp, class... _Args> -using __nothrow_invokable = __nothrow_invokable_r_imp<__invokable<_Fp, _Args...>::value, true, void, _Fp, _Args...>; +using __nothrow_invokable _LIBCPP_NODEBUG = + __nothrow_invokable_r_imp<__invokable<_Fp, _Args...>::value, true, void, _Fp, _Args...>; template <class _Fp, class... _Args> struct __invoke_of diff --git a/libcxx/include/__type_traits/is_always_bitcastable.h b/libcxx/include/__type_traits/is_always_bitcastable.h index 5bc650b41358..4c6c43c6571f 100644 --- a/libcxx/include/__type_traits/is_always_bitcastable.h +++ b/libcxx/include/__type_traits/is_always_bitcastable.h @@ -31,8 +31,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // considered bit-castable. template <class _From, class _To> struct __is_always_bitcastable { - using _UnqualFrom = __remove_cv_t<_From>; - using _UnqualTo = __remove_cv_t<_To>; + using _UnqualFrom _LIBCPP_NODEBUG = __remove_cv_t<_From>; + using _UnqualTo _LIBCPP_NODEBUG = __remove_cv_t<_To>; // clang-format off static const bool value = diff --git a/libcxx/include/__type_traits/is_char_like_type.h b/libcxx/include/__type_traits/is_char_like_type.h index 26205843047c..913c0821c8c6 100644 --- a/libcxx/include/__type_traits/is_char_like_type.h +++ b/libcxx/include/__type_traits/is_char_like_type.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _CharT> -using _IsCharLikeType = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >; +using _IsCharLikeType _LIBCPP_NODEBUG = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/is_equality_comparable.h b/libcxx/include/__type_traits/is_equality_comparable.h index 4397f743e5ee..3ee1839996be 100644 --- a/libcxx/include/__type_traits/is_equality_comparable.h +++ b/libcxx/include/__type_traits/is_equality_comparable.h @@ -80,7 +80,7 @@ struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*> }; template <class _Tp, class _Up> -using __libcpp_is_trivially_equality_comparable = +using __libcpp_is_trivially_equality_comparable _LIBCPP_NODEBUG = __libcpp_is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/is_execution_policy.h b/libcxx/include/__type_traits/is_execution_policy.h index 6884f17ba16c..a2d876db0309 100644 --- a/libcxx/include/__type_traits/is_execution_policy.h +++ b/libcxx/include/__type_traits/is_execution_policy.h @@ -50,7 +50,7 @@ __remove_parallel_policy(const _ExecutionPolicy& = _ExecutionPolicy{execution::_ // Removes the "parallel" part of an execution policy. // For example, turns par_unseq into unseq, and par into seq. template <class _ExecutionPolicy> -using __remove_parallel_policy_t = decltype(std::__remove_parallel_policy<_ExecutionPolicy>()); +using __remove_parallel_policy_t _LIBCPP_NODEBUG = decltype(std::__remove_parallel_policy<_ExecutionPolicy>()); _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/is_primary_template.h b/libcxx/include/__type_traits/is_primary_template.h index f308dfadc8ec..5fe6820bc7f7 100644 --- a/libcxx/include/__type_traits/is_primary_template.h +++ b/libcxx/include/__type_traits/is_primary_template.h @@ -21,10 +21,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp> -using __test_for_primary_template = __enable_if_t<_IsSame<_Tp, typename _Tp::__primary_template>::value>; +using __test_for_primary_template _LIBCPP_NODEBUG = + __enable_if_t<_IsSame<_Tp, typename _Tp::__primary_template>::value>; template <class _Tp> -using __is_primary_template = _IsValidExpansion<__test_for_primary_template, _Tp>; +using __is_primary_template _LIBCPP_NODEBUG = _IsValidExpansion<__test_for_primary_template, _Tp>; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/is_same.h b/libcxx/include/__type_traits/is_same.h index 9561b7b5d6da..400f870904d2 100644 --- a/libcxx/include/__type_traits/is_same.h +++ b/libcxx/include/__type_traits/is_same.h @@ -34,10 +34,10 @@ inline constexpr bool is_same_v = __is_same(_Tp, _Up); // (such as in a dependent return type). template <class _Tp, class _Up> -using _IsSame = _BoolConstant<__is_same(_Tp, _Up)>; +using _IsSame _LIBCPP_NODEBUG = _BoolConstant<__is_same(_Tp, _Up)>; template <class _Tp, class _Up> -using _IsNotSame = _BoolConstant<!__is_same(_Tp, _Up)>; +using _IsNotSame _LIBCPP_NODEBUG = _BoolConstant<!__is_same(_Tp, _Up)>; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/is_swappable.h b/libcxx/include/__type_traits/is_swappable.h index 221f017700a2..aa5eecd9abe0 100644 --- a/libcxx/include/__type_traits/is_swappable.h +++ b/libcxx/include/__type_traits/is_swappable.h @@ -41,10 +41,11 @@ inline const bool __is_nothrow_swappable_v = __is_nothrow_swappable_with_v<_Tp&, #ifndef _LIBCPP_CXX03_LANG template <class _Tp> -using __swap_result_t = __enable_if_t<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>; +using __swap_result_t _LIBCPP_NODEBUG = + __enable_if_t<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>; #else template <class> -using __swap_result_t = void; +using __swap_result_t _LIBCPP_NODEBUG = void; #endif template <class _Tp> diff --git a/libcxx/include/__type_traits/make_32_64_or_128_bit.h b/libcxx/include/__type_traits/make_32_64_or_128_bit.h index 70f84fcd1868..7016209ec9c0 100644 --- a/libcxx/include/__type_traits/make_32_64_or_128_bit.h +++ b/libcxx/include/__type_traits/make_32_64_or_128_bit.h @@ -31,7 +31,7 @@ template <class _Tp> requires(is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>) #endif // clang-format off -using __make_32_64_or_128_bit_t = +using __make_32_64_or_128_bit_t _LIBCPP_NODEBUG = __copy_unsigned_t<_Tp, __conditional_t<sizeof(_Tp) <= sizeof(int32_t), int32_t, __conditional_t<sizeof(_Tp) <= sizeof(int64_t), int64_t, diff --git a/libcxx/include/__type_traits/make_const_lvalue_ref.h b/libcxx/include/__type_traits/make_const_lvalue_ref.h index 469d4cb31ef7..f9955334de30 100644 --- a/libcxx/include/__type_traits/make_const_lvalue_ref.h +++ b/libcxx/include/__type_traits/make_const_lvalue_ref.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp> -using __make_const_lvalue_ref = const __libcpp_remove_reference_t<_Tp>&; +using __make_const_lvalue_ref _LIBCPP_NODEBUG = const __libcpp_remove_reference_t<_Tp>&; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/make_signed.h b/libcxx/include/__type_traits/make_signed.h index 8070690b3a7a..88513fea3006 100644 --- a/libcxx/include/__type_traits/make_signed.h +++ b/libcxx/include/__type_traits/make_signed.h @@ -26,24 +26,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if __has_builtin(__make_signed) template <class _Tp> -using __make_signed_t = __make_signed(_Tp); +using __make_signed_t _LIBCPP_NODEBUG = __make_signed(_Tp); #else -// clang-format off -typedef __type_list<signed char, - __type_list<signed short, - __type_list<signed int, - __type_list<signed long, - __type_list<signed long long, -# if _LIBCPP_HAS_INT128 - __type_list<__int128_t, -# endif - __nat +using __signed_types = + __type_list<signed char, + signed short, + signed int, + signed long, + signed long long # if _LIBCPP_HAS_INT128 - > + , + __int128_t # endif - > > > > > __signed_types; -// clang-format on + >; template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value> struct __make_signed{}; diff --git a/libcxx/include/__type_traits/make_unsigned.h b/libcxx/include/__type_traits/make_unsigned.h index 562f7bab8a7f..83ff8b7bb801 100644 --- a/libcxx/include/__type_traits/make_unsigned.h +++ b/libcxx/include/__type_traits/make_unsigned.h @@ -28,24 +28,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if __has_builtin(__make_unsigned) template <class _Tp> -using __make_unsigned_t = __make_unsigned(_Tp); +using __make_unsigned_t _LIBCPP_NODEBUG = __make_unsigned(_Tp); #else -// clang-format off -typedef __type_list<unsigned char, - __type_list<unsigned short, - __type_list<unsigned int, - __type_list<unsigned long, - __type_list<unsigned long long, -# if _LIBCPP_HAS_INT128 - __type_list<__uint128_t, -# endif - __nat +using __unsigned_types = + __type_list<unsigned char, + unsigned short, + unsigned int, + unsigned long, + unsigned long long # if _LIBCPP_HAS_INT128 - > + , + __uint128_t # endif - > > > > > __unsigned_types; -// clang-format on + >; template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value> struct __make_unsigned{}; @@ -92,7 +88,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __make_unsigned_t<_Tp> __to_unsigned_lik } template <class _Tp, class _Up> -using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, __make_unsigned_t<_Up>, _Up>; +using __copy_unsigned_t _LIBCPP_NODEBUG = __conditional_t<is_unsigned<_Tp>::value, __make_unsigned_t<_Up>, _Up>; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/maybe_const.h b/libcxx/include/__type_traits/maybe_const.h index 25fba58fb773..7ef742a123d0 100644 --- a/libcxx/include/__type_traits/maybe_const.h +++ b/libcxx/include/__type_traits/maybe_const.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <bool _Const, class _Tp> -using __maybe_const = __conditional_t<_Const, const _Tp, _Tp>; +using __maybe_const _LIBCPP_NODEBUG = __conditional_t<_Const, const _Tp, _Tp>; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/remove_all_extents.h b/libcxx/include/__type_traits/remove_all_extents.h index db7dab4a6c13..d46a3228b4ab 100644 --- a/libcxx/include/__type_traits/remove_all_extents.h +++ b/libcxx/include/__type_traits/remove_all_extents.h @@ -25,7 +25,7 @@ struct remove_all_extents { }; template <class _Tp> -using __remove_all_extents_t = __remove_all_extents(_Tp); +using __remove_all_extents_t _LIBCPP_NODEBUG = __remove_all_extents(_Tp); #else template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents { diff --git a/libcxx/include/__type_traits/remove_const.h b/libcxx/include/__type_traits/remove_const.h index a3f0648c4785..6250d9f53117 100644 --- a/libcxx/include/__type_traits/remove_const.h +++ b/libcxx/include/__type_traits/remove_const.h @@ -24,7 +24,7 @@ struct remove_const { }; template <class _Tp> -using __remove_const_t = __remove_const(_Tp); +using __remove_const_t _LIBCPP_NODEBUG = __remove_const(_Tp); #else template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const { diff --git a/libcxx/include/__type_traits/remove_const_ref.h b/libcxx/include/__type_traits/remove_const_ref.h index d3b334935a5b..e6583b396e6c 100644 --- a/libcxx/include/__type_traits/remove_const_ref.h +++ b/libcxx/include/__type_traits/remove_const_ref.h @@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp> -using __remove_const_ref_t = __remove_const_t<__libcpp_remove_reference_t<_Tp> >; +using __remove_const_ref_t _LIBCPP_NODEBUG = __remove_const_t<__libcpp_remove_reference_t<_Tp> >; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/remove_cv.h b/libcxx/include/__type_traits/remove_cv.h index 50e9f3e8aa78..16848e6d7112 100644 --- a/libcxx/include/__type_traits/remove_cv.h +++ b/libcxx/include/__type_traits/remove_cv.h @@ -24,10 +24,10 @@ struct remove_cv { #if defined(_LIBCPP_COMPILER_GCC) template <class _Tp> -using __remove_cv_t = typename remove_cv<_Tp>::type; +using __remove_cv_t _LIBCPP_NODEBUG = typename remove_cv<_Tp>::type; #else template <class _Tp> -using __remove_cv_t = __remove_cv(_Tp); +using __remove_cv_t _LIBCPP_NODEBUG = __remove_cv(_Tp); #endif #if _LIBCPP_STD_VER >= 14 diff --git a/libcxx/include/__type_traits/remove_cvref.h b/libcxx/include/__type_traits/remove_cvref.h index 55f894dbd1d8..e3c65944e33c 100644 --- a/libcxx/include/__type_traits/remove_cvref.h +++ b/libcxx/include/__type_traits/remove_cvref.h @@ -34,7 +34,7 @@ using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cvref(_Tp); #endif // __has_builtin(__remove_cvref) template <class _Tp, class _Up> -using __is_same_uncvref = _IsSame<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up> >; +using __is_same_uncvref _LIBCPP_NODEBUG = _IsSame<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up> >; #if _LIBCPP_STD_VER >= 20 template <class _Tp> diff --git a/libcxx/include/__type_traits/remove_extent.h b/libcxx/include/__type_traits/remove_extent.h index aceeb4706966..95a7971d7a9c 100644 --- a/libcxx/include/__type_traits/remove_extent.h +++ b/libcxx/include/__type_traits/remove_extent.h @@ -25,7 +25,7 @@ struct remove_extent { }; template <class _Tp> -using __remove_extent_t = __remove_extent(_Tp); +using __remove_extent_t _LIBCPP_NODEBUG = __remove_extent(_Tp); #else template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent { diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h index 6f98ed1a5d64..47cd1cd1d80f 100644 --- a/libcxx/include/__type_traits/remove_pointer.h +++ b/libcxx/include/__type_traits/remove_pointer.h @@ -25,10 +25,10 @@ struct remove_pointer { # ifdef _LIBCPP_COMPILER_GCC template <class _Tp> -using __remove_pointer_t = typename remove_pointer<_Tp>::type; +using __remove_pointer_t _LIBCPP_NODEBUG = typename remove_pointer<_Tp>::type; # else template <class _Tp> -using __remove_pointer_t = __remove_pointer(_Tp); +using __remove_pointer_t _LIBCPP_NODEBUG = __remove_pointer(_Tp); # endif #else // clang-format off diff --git a/libcxx/include/__type_traits/remove_reference.h b/libcxx/include/__type_traits/remove_reference.h index ba67891758ad..f68815691ac0 100644 --- a/libcxx/include/__type_traits/remove_reference.h +++ b/libcxx/include/__type_traits/remove_reference.h @@ -24,7 +24,7 @@ struct remove_reference { }; template <class _Tp> -using __libcpp_remove_reference_t = __remove_reference_t(_Tp); +using __libcpp_remove_reference_t _LIBCPP_NODEBUG = __remove_reference_t(_Tp); #elif __has_builtin(__remove_reference) template <class _Tp> struct remove_reference { diff --git a/libcxx/include/__type_traits/remove_volatile.h b/libcxx/include/__type_traits/remove_volatile.h index 7600ae0ec516..099945df0124 100644 --- a/libcxx/include/__type_traits/remove_volatile.h +++ b/libcxx/include/__type_traits/remove_volatile.h @@ -24,7 +24,7 @@ struct remove_volatile { }; template <class _Tp> -using __remove_volatile_t = __remove_volatile(_Tp); +using __remove_volatile_t _LIBCPP_NODEBUG = __remove_volatile(_Tp); #else template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile { diff --git a/libcxx/include/__type_traits/type_list.h b/libcxx/include/__type_traits/type_list.h index b4898b36e2d9..34d78fc97c97 100644 --- a/libcxx/include/__type_traits/type_list.h +++ b/libcxx/include/__type_traits/type_list.h @@ -11,6 +11,7 @@ #include <__config> #include <__cstddef/size_t.h> +#include <__type_traits/enable_if.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -18,23 +19,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Hp, class _Tp> -struct __type_list { - typedef _Hp _Head; - typedef _Tp _Tail; +template <class... _Types> +struct __type_list {}; + +template <class> +struct __type_list_head; + +template <class _Head, class... _Tail> +struct __type_list_head<__type_list<_Head, _Tail...> > { + using type _LIBCPP_NODEBUG = _Head; }; -template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> +template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename __type_list_head<_TypeList>::type)> struct __find_first; -template <class _Hp, class _Tp, size_t _Size> -struct __find_first<__type_list<_Hp, _Tp>, _Size, true> { - using type _LIBCPP_NODEBUG = _Hp; +template <class _Head, class... _Tail, size_t _Size> +struct __find_first<__type_list<_Head, _Tail...>, _Size, true> { + using type _LIBCPP_NODEBUG = _Head; }; -template <class _Hp, class _Tp, size_t _Size> -struct __find_first<__type_list<_Hp, _Tp>, _Size, false> { - using type _LIBCPP_NODEBUG = typename __find_first<_Tp, _Size>::type; +template <class _Head, class... _Tail, size_t _Size> +struct __find_first<__type_list<_Head, _Tail...>, _Size, false> { + using type _LIBCPP_NODEBUG = typename __find_first<__type_list<_Tail...>, _Size>::type; }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/unwrap_ref.h b/libcxx/include/__type_traits/unwrap_ref.h index 74c4fde915c3..11a069d66302 100644 --- a/libcxx/include/__type_traits/unwrap_ref.h +++ b/libcxx/include/__type_traits/unwrap_ref.h @@ -29,6 +29,9 @@ struct __unwrap_reference<reference_wrapper<_Tp> > { using type _LIBCPP_NODEBUG = _Tp&; }; +template <class _Tp> +using __unwrap_ref_decay_t _LIBCPP_NODEBUG = typename __unwrap_reference<__decay_t<_Tp> >::type; + #if _LIBCPP_STD_VER >= 20 template <class _Tp> struct unwrap_reference : __unwrap_reference<_Tp> {}; @@ -40,19 +43,9 @@ template <class _Tp> struct unwrap_ref_decay : unwrap_reference<__decay_t<_Tp> > {}; template <class _Tp> -using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; +using unwrap_ref_decay_t = __unwrap_ref_decay_t<_Tp>; #endif // _LIBCPP_STD_VER >= 20 -template <class _Tp> -struct __unwrap_ref_decay -#if _LIBCPP_STD_VER >= 20 - : unwrap_ref_decay<_Tp> -#else - : __unwrap_reference<__decay_t<_Tp> > -#endif -{ -}; - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H diff --git a/libcxx/include/__type_traits/void_t.h b/libcxx/include/__type_traits/void_t.h index 985bba02e72f..8adadfa69637 100644 --- a/libcxx/include/__type_traits/void_t.h +++ b/libcxx/include/__type_traits/void_t.h @@ -23,7 +23,7 @@ using void_t = void; #endif template <class...> -using __void_t = void; +using __void_t _LIBCPP_NODEBUG = void; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__utility/exception_guard.h b/libcxx/include/__utility/exception_guard.h index 71e52fdb4b2a..a6b4ec521107 100644 --- a/libcxx/include/__utility/exception_guard.h +++ b/libcxx/include/__utility/exception_guard.h @@ -126,10 +126,10 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_noexceptions); #if !_LIBCPP_HAS_EXCEPTIONS template <class _Rollback> -using __exception_guard = __exception_guard_noexceptions<_Rollback>; +using __exception_guard _LIBCPP_NODEBUG = __exception_guard_noexceptions<_Rollback>; #else template <class _Rollback> -using __exception_guard = __exception_guard_exceptions<_Rollback>; +using __exception_guard _LIBCPP_NODEBUG = __exception_guard_exceptions<_Rollback>; #endif template <class _Rollback> diff --git a/libcxx/include/__utility/forward_like.h b/libcxx/include/__utility/forward_like.h index 67bdf6d054ea..409f716cfbce 100644 --- a/libcxx/include/__utility/forward_like.h +++ b/libcxx/include/__utility/forward_like.h @@ -26,13 +26,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 template <class _Ap, class _Bp> -using _CopyConst = _If<is_const_v<_Ap>, const _Bp, _Bp>; +using _CopyConst _LIBCPP_NODEBUG = _If<is_const_v<_Ap>, const _Bp, _Bp>; template <class _Ap, class _Bp> -using _OverrideRef = _If<is_rvalue_reference_v<_Ap>, remove_reference_t<_Bp>&&, _Bp&>; +using _OverrideRef _LIBCPP_NODEBUG = _If<is_rvalue_reference_v<_Ap>, remove_reference_t<_Bp>&&, _Bp&>; template <class _Ap, class _Bp> -using _ForwardLike = _OverrideRef<_Ap&&, _CopyConst<remove_reference_t<_Ap>, remove_reference_t<_Bp>>>; +using _ForwardLike _LIBCPP_NODEBUG = _OverrideRef<_Ap&&, _CopyConst<remove_reference_t<_Ap>, remove_reference_t<_Bp>>>; template <class _Tp, class _Up> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto diff --git a/libcxx/include/__utility/in_place.h b/libcxx/include/__utility/in_place.h index edaa4e02c55f..9b48446d8370 100644 --- a/libcxx/include/__utility/in_place.h +++ b/libcxx/include/__utility/in_place.h @@ -47,7 +47,7 @@ template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_type {}; template <class _Tp> -using __is_inplace_type = __is_inplace_type_imp<__remove_cvref_t<_Tp>>; +using __is_inplace_type _LIBCPP_NODEBUG = __is_inplace_type_imp<__remove_cvref_t<_Tp>>; template <class _Tp> struct __is_inplace_index_imp : false_type {}; @@ -55,7 +55,7 @@ template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : true_type {}; template <class _Tp> -using __is_inplace_index = __is_inplace_index_imp<__remove_cvref_t<_Tp>>; +using __is_inplace_index _LIBCPP_NODEBUG = __is_inplace_index_imp<__remove_cvref_t<_Tp>>; #endif // _LIBCPP_STD_VER >= 17 diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h index 35eb606ee37f..2c1ff3c543e8 100644 --- a/libcxx/include/__utility/integer_sequence.h +++ b/libcxx/include/__utility/integer_sequence.h @@ -25,19 +25,19 @@ struct __tuple_indices; template <class _IdxType, _IdxType... _Values> struct __integer_sequence { template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType> - using __convert = _ToIndexSeq<_ToIndexType, _Values...>; + using __convert _LIBCPP_NODEBUG = _ToIndexSeq<_ToIndexType, _Values...>; template <size_t _Sp> - using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; + using __to_tuple_indices _LIBCPP_NODEBUG = __tuple_indices<(_Values + _Sp)...>; }; #if __has_builtin(__make_integer_seq) template <size_t _Ep, size_t _Sp> -using __make_indices_imp = +using __make_indices_imp _LIBCPP_NODEBUG = typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template __to_tuple_indices<_Sp>; #elif __has_builtin(__integer_pack) template <size_t _Ep, size_t _Sp> -using __make_indices_imp = +using __make_indices_imp _LIBCPP_NODEBUG = typename __integer_sequence<size_t, __integer_pack(_Ep - _Sp)...>::template __to_tuple_indices<_Sp>; #else # error "No known way to get an integer pack from the compiler" diff --git a/libcxx/include/__utility/move.h b/libcxx/include/__utility/move.h index 015986f610bd..bc16697b5c89 100644 --- a/libcxx/include/__utility/move.h +++ b/libcxx/include/__utility/move.h @@ -33,7 +33,7 @@ move(_LIBCPP_LIFETIMEBOUND _Tp&& __t) _NOEXCEPT { } template <class _Tp> -using __move_if_noexcept_result_t = +using __move_if_noexcept_result_t _LIBCPP_NODEBUG = __conditional_t<!is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, const _Tp&, _Tp&&>; template <class _Tp> diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h index f9d0f4e47231..7689ab2a48c6 100644 --- a/libcxx/include/__utility/pair.h +++ b/libcxx/include/__utility/pair.h @@ -71,7 +71,7 @@ struct _LIBCPP_TEMPLATE_VIS pair _T1 first; _T2 second; - using __trivially_relocatable = + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value, pair, void>; @@ -532,11 +532,9 @@ swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x #endif template <class _T1, class _T2> -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> > make_pair(_T1&& __t1, _T2&& __t2) { - return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>( - std::forward<_T1>(__t1), std::forward<_T2>(__t2)); + return pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> >(std::forward<_T1>(__t1), std::forward<_T2>(__t2)); } template <class _T1, class _T2> diff --git a/libcxx/include/__utility/swap.h b/libcxx/include/__utility/swap.h index 666d6d50f0d9..b4311540d36e 100644 --- a/libcxx/include/__utility/swap.h +++ b/libcxx/include/__utility/swap.h @@ -31,10 +31,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_CXX03_LANG template <class _Tp> -using __swap_result_t = __enable_if_t<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>; +using __swap_result_t _LIBCPP_NODEBUG = + __enable_if_t<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>; #else template <class> -using __swap_result_t = void; +using __swap_result_t _LIBCPP_NODEBUG = void; #endif template <class _Tp> diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 6ba7ba7bcf72..ddbf1235b906 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -114,7 +114,7 @@ public: // - pointer: may be trivially relocatable, so it's checked // - allocator_type: may be trivially relocatable, so it's checked // vector doesn't contain any self-references, so it's trivially relocatable if its members are. - using __trivially_relocatable = __conditional_t< + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t< __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, vector, void>; diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h index 525fc35b26cc..6c6605fb3bd0 100644 --- a/libcxx/include/__vector/vector_bool.h +++ b/libcxx/include/__vector/vector_bool.h @@ -275,17 +275,33 @@ public: } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) { return __make_ref(__n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds"); + return __make_ref(__n); + } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __n) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds"); return __make_ref(__n); } - _LIBCPP_HIDE_FROM_ABI reference at(size_type __n); - _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() { return __make_ref(0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const { return __make_ref(0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() { return __make_ref(__size_ - 1); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const { return __make_ref(__size_ - 1); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector"); + return __make_ref(0); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector"); + return __make_ref(0); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector"); + return __make_ref(__size_ - 1); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector"); + return __make_ref(__size_ - 1); + } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(const value_type& __x); #if _LIBCPP_STD_VER >= 14 @@ -310,7 +326,10 @@ public: } #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() { --__size_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::pop_back called on an empty vector"); + --__size_; + } #if _LIBCPP_STD_VER >= 14 template <class... _Args> @@ -442,7 +461,6 @@ private: template <class _InputIterator, class _Sentinel> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append(size_type __n, const_reference __x); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference __make_ref(size_type __pos) _NOEXCEPT { return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word); } @@ -854,14 +872,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::shrink_to_fit() _NO } template <class _Allocator> -typename vector<bool, _Allocator>::reference vector<bool, _Allocator>::at(size_type __n) { +_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::reference vector<bool, _Allocator>::at(size_type __n) { if (__n >= size()) this->__throw_out_of_range(); return (*this)[__n]; } template <class _Allocator> -typename vector<bool, _Allocator>::const_reference vector<bool, _Allocator>::at(size_type __n) const { +_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::const_reference +vector<bool, _Allocator>::at(size_type __n) const { if (__n >= size()) this->__throw_out_of_range(); return (*this)[__n]; @@ -995,6 +1014,8 @@ vector<bool, _Allocator>::__insert_with_size( template <class _Allocator> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator vector<bool, _Allocator>::erase(const_iterator __position) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __position != end(), "vector<bool>::erase(iterator) called with a non-dereferenceable iterator"); iterator __r = __const_iterator_cast(__position); std::copy(__position + 1, this->cend(), __r); --__size_; @@ -1004,6 +1025,8 @@ vector<bool, _Allocator>::erase(const_iterator __position) { template <class _Allocator> _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator vector<bool, _Allocator>::erase(const_iterator __first, const_iterator __last) { + _LIBCPP_ASSERT_VALID_INPUT_RANGE( + __first <= __last, "vector<bool>::erase(iterator, iterator) called with an invalid range"); iterator __r = __const_iterator_cast(__first); difference_type __d = __last - __first; std::copy(__last, this->cend(), __r); diff --git a/libcxx/include/any b/libcxx/include/any index 934c4dbd45a6..786e86b5ccd8 100644 --- a/libcxx/include/any +++ b/libcxx/include/any @@ -149,11 +149,11 @@ _LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT; namespace __any_imp { _LIBCPP_SUPPRESS_DEPRECATED_PUSH -using _Buffer = aligned_storage_t<3 * sizeof(void*), alignof(void*)>; +using _Buffer _LIBCPP_NODEBUG = aligned_storage_t<3 * sizeof(void*), alignof(void*)>; _LIBCPP_SUPPRESS_DEPRECATED_POP template <class _Tp> -using _IsSmallObject = +using _IsSmallObject _LIBCPP_NODEBUG = integral_constant<bool, sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 && is_nothrow_move_constructible<_Tp>::value >; @@ -185,7 +185,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool __compare_typeid(type_info const* __id, const } template <class _Tp> -using _Handler = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; +using _Handler _LIBCPP_NODEBUG = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; } // namespace __any_imp @@ -278,8 +278,9 @@ public: # endif private: - typedef __any_imp::_Action _Action; - using _HandleFuncPtr = void* (*)(_Action, any const*, any*, const type_info*, const void* __fallback_info); + using _Action _LIBCPP_NODEBUG = __any_imp::_Action; + using _HandleFuncPtr + _LIBCPP_NODEBUG = void* (*)(_Action, any const*, any*, const type_info*, const void* __fallback_info); union _Storage { _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {} diff --git a/libcxx/include/array b/libcxx/include/array index 516d96538f5a..1b9bcd6891d9 100644 --- a/libcxx/include/array +++ b/libcxx/include/array @@ -173,15 +173,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array { - using __trivially_relocatable = __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>; + using __trivially_relocatable _LIBCPP_NODEBUG = + __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>; // types: - using __self = array; - using value_type = _Tp; - using reference = value_type&; - using const_reference = const value_type&; - using pointer = value_type*; - using const_pointer = const value_type*; + using __self _LIBCPP_NODEBUG = array; + using value_type = _Tp; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) using iterator = __static_bounded_iter<pointer, _Size>; using const_iterator = __static_bounded_iter<const_pointer, _Size>; @@ -299,12 +300,12 @@ struct _LIBCPP_TEMPLATE_VIS array { template <class _Tp> struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> { // types: - using __self = array; - using value_type = _Tp; - using reference = value_type&; - using const_reference = const value_type&; - using pointer = value_type*; - using const_pointer = const value_type*; + using __self _LIBCPP_NODEBUG = array; + using value_type = _Tp; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) using iterator = __static_bounded_iter<pointer, 0>; using const_iterator = __static_bounded_iter<const_pointer, 0>; @@ -320,7 +321,7 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> { using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; - using _EmptyType = __conditional_t<is_const<_Tp>::value, const __empty, __empty>; + using _EmptyType _LIBCPP_NODEBUG = __conditional_t<is_const<_Tp>::value, const __empty, __empty>; struct _ArrayInStructT { _Tp __data_[1]; diff --git a/libcxx/include/barrier b/libcxx/include/barrier index 6861532b02ba..91dfa9720a37 100644 --- a/libcxx/include/barrier +++ b/libcxx/include/barrier @@ -95,7 +95,7 @@ It looks different from literature pseudocode for two main reasons: */ -using __barrier_phase_t = uint8_t; +using __barrier_phase_t _LIBCPP_NODEBUG = uint8_t; class __barrier_algorithm_base; diff --git a/libcxx/include/ccomplex b/libcxx/include/ccomplex index 10eb8a36e417..ee7e088aac54 100644 --- a/libcxx/include/ccomplex +++ b/libcxx/include/ccomplex @@ -28,13 +28,14 @@ # if _LIBCPP_STD_VER >= 20 -using __standard_header_ccomplex _LIBCPP_DEPRECATED_("removed in C++20. Include <complex> instead.") = void; -using __use_standard_header_ccomplex = __standard_header_ccomplex; +using __standard_header_ccomplex + _LIBCPP_DEPRECATED_("removed in C++20. Include <complex> instead.") _LIBCPP_NODEBUG = void; +using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex; # elif _LIBCPP_STD_VER >= 17 -using __standard_header_ccomplex _LIBCPP_DEPRECATED_("Include <complex> instead.") = void; -using __use_standard_header_ccomplex = __standard_header_ccomplex; +using __standard_header_ccomplex _LIBCPP_DEPRECATED_("Include <complex> instead.") _LIBCPP_NODEBUG = void; +using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex; # endif #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) diff --git a/libcxx/include/ciso646 b/libcxx/include/ciso646 index 5b956401430a..34164362dc10 100644 --- a/libcxx/include/ciso646 +++ b/libcxx/include/ciso646 @@ -26,8 +26,9 @@ # if _LIBCPP_STD_VER >= 20 -using __standard_header_ciso646 _LIBCPP_DEPRECATED_("removed in C++20. Include <version> instead.") = void; -using __use_standard_header_ciso646 = __standard_header_ciso646; +using __standard_header_ciso646 + _LIBCPP_DEPRECATED_("removed in C++20. Include <version> instead.") _LIBCPP_NODEBUG = void; +using __use_standard_header_ciso646 _LIBCPP_NODEBUG = __standard_header_ciso646; # endif #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) diff --git a/libcxx/include/complex b/libcxx/include/complex index bc73f313c2ce..df18159595b3 100644 --- a/libcxx/include/complex +++ b/libcxx/include/complex @@ -400,7 +400,7 @@ class _LIBCPP_TEMPLATE_VIS complex<long double>; struct __from_builtin_tag {}; template <class _Tp> -using __complex_t = +using __complex_t _LIBCPP_NODEBUG = __conditional_t<is_same<_Tp, float>::value, _Complex float, __conditional_t<is_same<_Tp, double>::value, _Complex double, _Complex long double> >; diff --git a/libcxx/include/cstdalign b/libcxx/include/cstdalign index 6a277e467300..7f8dd1e1fbaf 100644 --- a/libcxx/include/cstdalign +++ b/libcxx/include/cstdalign @@ -45,13 +45,13 @@ Macros: # if _LIBCPP_STD_VER >= 20 -using __standard_header_cstdalign _LIBCPP_DEPRECATED_("removed in C++20.") = void; -using __use_standard_header_cstdalign = __standard_header_cstdalign; +using __standard_header_cstdalign _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void; +using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign; # elif _LIBCPP_STD_VER >= 17 -using __standard_header_cstdalign _LIBCPP_DEPRECATED = void; -using __use_standard_header_cstdalign = __standard_header_cstdalign; +using __standard_header_cstdalign _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void; +using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign; # endif #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) diff --git a/libcxx/include/cstdbool b/libcxx/include/cstdbool index a12954f07398..a432d5f08b9a 100644 --- a/libcxx/include/cstdbool +++ b/libcxx/include/cstdbool @@ -33,13 +33,13 @@ Macros: # if _LIBCPP_STD_VER >= 20 -using __standard_header_cstdbool _LIBCPP_DEPRECATED_("removed in C++20.") = void; -using __use_standard_header_cstdbool = __standard_header_cstdbool; +using __standard_header_cstdbool _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void; +using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool; # elif _LIBCPP_STD_VER >= 17 -using __standard_header_cstdbool _LIBCPP_DEPRECATED = void; -using __use_standard_header_cstdbool = __standard_header_cstdbool; +using __standard_header_cstdbool _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void; +using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool; # endif #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) diff --git a/libcxx/include/ctgmath b/libcxx/include/ctgmath index 237f474f01c2..db0786f1e2c4 100644 --- a/libcxx/include/ctgmath +++ b/libcxx/include/ctgmath @@ -30,13 +30,14 @@ # if _LIBCPP_STD_VER >= 20 -using __standard_header_ctgmath _LIBCPP_DEPRECATED_("removed in C++20. Include <cmath> and <complex> instead.") = void; -using __use_standard_header_ctgmath = __standard_header_ctgmath; +using __standard_header_ctgmath + _LIBCPP_DEPRECATED_("removed in C++20. Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void; +using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath; # elif _LIBCPP_STD_VER >= 17 -using __standard_header_ctgmath _LIBCPP_DEPRECATED_("Include <cmath> and <complex> instead.") = void; -using __use_standard_header_ctgmath = __standard_header_ctgmath; +using __standard_header_ctgmath _LIBCPP_DEPRECATED_("Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void; +using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath; # endif diff --git a/libcxx/include/deque b/libcxx/include/deque index 883332f1ebdc..df3094cff7f8 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -456,12 +456,13 @@ template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, struct __segmented_iterator_traits< __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > { private: - using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; + using _Iterator _LIBCPP_NODEBUG = + __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>; public: - using __is_segmented_iterator = true_type; - using __segment_iterator = _MapPointer; - using __local_iterator = _Pointer; + using __is_segmented_iterator _LIBCPP_NODEBUG = true_type; + using __segment_iterator _LIBCPP_NODEBUG = _MapPointer; + using __local_iterator _LIBCPP_NODEBUG = _Pointer; static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; } static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; } @@ -491,8 +492,8 @@ public: using value_type = _Tp; - using allocator_type = _Allocator; - using __alloc_traits = allocator_traits<allocator_type>; + using allocator_type = _Allocator; + using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<allocator_type>; static_assert(__check_valid_allocator<allocator_type>::value, ""); static_assert(is_same<typename allocator_type::value_type, value_type>::value, "Allocator::value_type must be same type as value_type"); @@ -503,13 +504,13 @@ public: using pointer = typename __alloc_traits::pointer; using const_pointer = typename __alloc_traits::const_pointer; - using __pointer_allocator = __rebind_alloc<__alloc_traits, pointer>; - using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>; - using __map = __split_buffer<pointer, __pointer_allocator>; - using __map_alloc_traits = allocator_traits<__pointer_allocator>; - using __map_pointer = typename __map_alloc_traits::pointer; - using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; - using __map_const_iterator = typename __map::const_iterator; + using __pointer_allocator _LIBCPP_NODEBUG = __rebind_alloc<__alloc_traits, pointer>; + using __const_pointer_allocator _LIBCPP_NODEBUG = __rebind_alloc<__alloc_traits, const_pointer>; + using __map _LIBCPP_NODEBUG = __split_buffer<pointer, __pointer_allocator>; + using __map_alloc_traits _LIBCPP_NODEBUG = allocator_traits<__pointer_allocator>; + using __map_pointer _LIBCPP_NODEBUG = typename __map_alloc_traits::pointer; + using __map_const_pointer _LIBCPP_NODEBUG = typename allocator_traits<__const_pointer_allocator>::const_pointer; + using __map_const_iterator _LIBCPP_NODEBUG = typename __map::const_iterator; using reference = value_type&; using const_reference = const value_type&; @@ -525,7 +526,7 @@ public: // - size_type: is always trivially relocatable, since it is required to be an integral type // - allocator_type: may not be trivially relocatable, so it's checked // None of these are referencing the `deque` itself, so if all of them are trivially relocatable, `deque` is too. - using __trivially_relocatable = __conditional_t< + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t< __libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, deque, void>; diff --git a/libcxx/include/experimental/__simd/scalar.h b/libcxx/include/experimental/__simd/scalar.h index da318d2f4650..20c8b02c6589 100644 --- a/libcxx/include/experimental/__simd/scalar.h +++ b/libcxx/include/experimental/__simd/scalar.h @@ -49,8 +49,8 @@ struct __mask_storage<_Tp, simd_abi::__scalar> : __simd_storage<bool, simd_abi:: template <class _Tp> struct __simd_operations<_Tp, simd_abi::__scalar> { - using _SimdStorage = __simd_storage<_Tp, simd_abi::__scalar>; - using _MaskStorage = __mask_storage<_Tp, simd_abi::__scalar>; + using _SimdStorage _LIBCPP_NODEBUG = __simd_storage<_Tp, simd_abi::__scalar>; + using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__scalar>; static _LIBCPP_HIDE_FROM_ABI _SimdStorage __broadcast(_Tp __v) noexcept { return {__v}; } @@ -86,7 +86,7 @@ struct __simd_operations<_Tp, simd_abi::__scalar> { template <class _Tp> struct __mask_operations<_Tp, simd_abi::__scalar> { - using _MaskStorage = __mask_storage<_Tp, simd_abi::__scalar>; + using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__scalar>; static _LIBCPP_HIDE_FROM_ABI _MaskStorage __broadcast(bool __v) noexcept { return {__v}; } diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/simd.h index fd919e75e32f..2fd2b2644d0b 100644 --- a/libcxx/include/experimental/__simd/simd.h +++ b/libcxx/include/experimental/__simd/simd.h @@ -43,8 +43,8 @@ public: // TODO: implement simd class template <class _Tp, class _Abi> class simd : public __simd_int_operators<simd<_Tp, _Abi>, __simd_operations<_Tp, _Abi>, is_integral_v<_Tp>> { - using _Impl = __simd_operations<_Tp, _Abi>; - using _Storage = typename _Impl::_SimdStorage; + using _Impl _LIBCPP_NODEBUG = __simd_operations<_Tp, _Abi>; + using _Storage _LIBCPP_NODEBUG = typename _Impl::_SimdStorage; _Storage __s_; diff --git a/libcxx/include/experimental/__simd/simd_mask.h b/libcxx/include/experimental/__simd/simd_mask.h index 6b6f671bf3e6..a11766545b43 100644 --- a/libcxx/include/experimental/__simd/simd_mask.h +++ b/libcxx/include/experimental/__simd/simd_mask.h @@ -27,8 +27,8 @@ inline namespace parallelism_v2 { // TODO: implement simd_mask class template <class _Tp, class _Abi> class simd_mask { - using _Impl = __mask_operations<_Tp, _Abi>; - using _Storage = typename _Impl::_MaskStorage; + using _Impl _LIBCPP_NODEBUG = __mask_operations<_Tp, _Abi>; + using _Storage _LIBCPP_NODEBUG = typename _Impl::_MaskStorage; _Storage __s_; diff --git a/libcxx/include/experimental/__simd/vec_ext.h b/libcxx/include/experimental/__simd/vec_ext.h index abc7e9595be9..2a4b8c748f86 100644 --- a/libcxx/include/experimental/__simd/vec_ext.h +++ b/libcxx/include/experimental/__simd/vec_ext.h @@ -55,8 +55,8 @@ struct __mask_storage<_Tp, simd_abi::__vec_ext<_Np>> template <class _Tp, int _Np> struct __simd_operations<_Tp, simd_abi::__vec_ext<_Np>> { - using _SimdStorage = __simd_storage<_Tp, simd_abi::__vec_ext<_Np>>; - using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>; + using _SimdStorage _LIBCPP_NODEBUG = __simd_storage<_Tp, simd_abi::__vec_ext<_Np>>; + using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>; static _LIBCPP_HIDE_FROM_ABI _SimdStorage __broadcast(_Tp __v) noexcept { _SimdStorage __result; @@ -101,7 +101,7 @@ struct __simd_operations<_Tp, simd_abi::__vec_ext<_Np>> { template <class _Tp, int _Np> struct __mask_operations<_Tp, simd_abi::__vec_ext<_Np>> { - using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>; + using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>; static _LIBCPP_HIDE_FROM_ABI _MaskStorage __broadcast(bool __v) noexcept { _MaskStorage __result; diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list index c1ab155d5a13..f3b9617ab2e0 100644 --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -202,6 +202,7 @@ template <class T, class Allocator, class Predicate> # include <__algorithm/lexicographical_compare.h> # include <__algorithm/lexicographical_compare_three_way.h> # include <__algorithm/min.h> +# include <__assert> # include <__config> # include <__cstddef/nullptr_t.h> # include <__iterator/distance.h> @@ -316,7 +317,8 @@ struct __forward_begin_node { }; template <class _Tp, class _VoidPtr> -using __begin_node_of = __forward_begin_node<__rebind_pointer_t<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> > >; +using __begin_node_of _LIBCPP_NODEBUG = + __forward_begin_node<__rebind_pointer_t<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> > >; template <class _Tp, class _VoidPtr> struct __forward_list_node : public __begin_node_of<_Tp, _VoidPtr> { @@ -766,8 +768,14 @@ public: return std::min<size_type>(__node_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max()); } - _LIBCPP_HIDE_FROM_ABI reference front() { return __base::__before_begin()->__next_->__get_value(); } - _LIBCPP_HIDE_FROM_ABI const_reference front() const { return __base::__before_begin()->__next_->__get_value(); } + _LIBCPP_HIDE_FROM_ABI reference front() { + _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list"); + return __base::__before_begin()->__next_->__get_value(); + } + _LIBCPP_HIDE_FROM_ABI const_reference front() const { + _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list"); + return __base::__before_begin()->__next_->__get_value(); + } # ifndef _LIBCPP_CXX03_LANG # if _LIBCPP_STD_VER >= 17 @@ -1085,6 +1093,7 @@ void forward_list<_Tp, _Alloc>::push_front(const value_type& __v) { template <class _Tp, class _Alloc> void forward_list<_Tp, _Alloc>::pop_front() { + _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::pop_front called on an empty list"); __node_pointer __p = __base::__before_begin()->__next_; __base::__before_begin()->__next_ = __p->__next_; this->__delete_node(__p); diff --git a/libcxx/include/ios b/libcxx/include/ios index 7c2ee83d4624..98a088266539 100644 --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -629,9 +629,9 @@ private: basic_ostream<char_type, traits_type>* __tie_; # if defined(_LIBCPP_ABI_IOS_ALLOW_ARBITRARY_FILL_VALUE) - using _FillType = _FillHelper<traits_type>; + using _FillType _LIBCPP_NODEBUG = _FillHelper<traits_type>; # else - using _FillType = _SentinelValueFill<traits_type>; + using _FillType _LIBCPP_NODEBUG = _SentinelValueFill<traits_type>; # endif mutable _FillType __fill_; }; diff --git a/libcxx/include/optional b/libcxx/include/optional index 165e0f16cab9..c325140ee66f 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -353,8 +353,8 @@ struct __optional_destruct_base<_Tp, true> { template <class _Tp, bool = is_reference<_Tp>::value> struct __optional_storage_base : __optional_destruct_base<_Tp> { - using __base = __optional_destruct_base<_Tp>; - using value_type = _Tp; + using __base _LIBCPP_NODEBUG = __optional_destruct_base<_Tp>; + using value_type = _Tp; using __base::__base; _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; } @@ -396,8 +396,8 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> { // to ensure we can make the change in an ABI-compatible manner. template <class _Tp> struct __optional_storage_base<_Tp, true> { - using value_type = _Tp; - using __raw_type = remove_reference_t<_Tp>; + using value_type = _Tp; + using __raw_type _LIBCPP_NODEBUG = remove_reference_t<_Tp>; __raw_type* __value_; template <class _Up> @@ -555,11 +555,11 @@ struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp }; template <class _Tp> -using __optional_sfinae_ctor_base_t = +using __optional_sfinae_ctor_base_t _LIBCPP_NODEBUG = __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >; template <class _Tp> -using __optional_sfinae_assign_base_t = +using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG = __sfinae_assign_base< (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value), (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) >; @@ -583,12 +583,13 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES optional : private __optional_move_assign_base<_Tp>, private __optional_sfinae_ctor_base_t<_Tp>, private __optional_sfinae_assign_base_t<_Tp> { - using __base = __optional_move_assign_base<_Tp>; + using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>; public: using value_type = _Tp; - using __trivially_relocatable = conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>; + using __trivially_relocatable _LIBCPP_NODEBUG = + conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>; private: // Disable the reference extension using this static assert. @@ -613,7 +614,7 @@ private: } }; template <class _Up> - using _CheckOptionalArgsCtor = + using _CheckOptionalArgsCtor _LIBCPP_NODEBUG = _If< _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && _IsNotSame<__remove_cvref_t<_Up>, optional>::value && (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value), _CheckOptionalArgsConstructor, @@ -621,7 +622,7 @@ private: template <class _QualUp> struct _CheckOptionalLikeConstructor { template <class _Up, class _Opt = optional<_Up>> - using __check_constructible_from_opt = + using __check_constructible_from_opt _LIBCPP_NODEBUG = _Or< is_constructible<_Tp, _Opt&>, is_constructible<_Tp, _Opt const&>, is_constructible<_Tp, _Opt&&>, @@ -631,7 +632,7 @@ private: is_convertible<_Opt&&, _Tp>, is_convertible<_Opt const&&, _Tp> >; template <class _Up, class _Opt = optional<_Up>> - using __check_assignable_from_opt = + using __check_assignable_from_opt _LIBCPP_NODEBUG = _Or< is_assignable<_Tp&, _Opt&>, is_assignable<_Tp&, _Opt const&>, is_assignable<_Tp&, _Opt&&>, @@ -655,12 +656,12 @@ private: }; template <class _Up, class _QualUp> - using _CheckOptionalLikeCtor = + using _CheckOptionalLikeCtor _LIBCPP_NODEBUG = _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value, _CheckOptionalLikeConstructor<_QualUp>, __check_tuple_constructor_fail >; template <class _Up, class _QualUp> - using _CheckOptionalLikeAssign = + using _CheckOptionalLikeAssign _LIBCPP_NODEBUG = _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value, _CheckOptionalLikeConstructor<_QualUp>, __check_tuple_constructor_fail >; diff --git a/libcxx/include/ratio b/libcxx/include/ratio index b35e2bd9dad6..2b5e34cbcd18 100644 --- a/libcxx/include/ratio +++ b/libcxx/include/ratio @@ -465,7 +465,7 @@ struct _LIBCPP_TEMPLATE_VIS ratio_greater_equal : _BoolConstant<!ratio_less<_R1, }; template <class _R1, class _R2> -using __ratio_gcd = ratio<__static_gcd<_R1::num, _R2::num>, __static_lcm<_R1::den, _R2::den> >; +using __ratio_gcd _LIBCPP_NODEBUG = ratio<__static_gcd<_R1::num, _R2::num>, __static_lcm<_R1::den, _R2::den> >; # if _LIBCPP_STD_VER >= 17 template <class _R1, class _R2> diff --git a/libcxx/include/regex b/libcxx/include/regex index 15ec15a6985e..5cad0bc4b812 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -4229,7 +4229,8 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator==(const sub_match<_BiIter>& __x, cons # if _LIBCPP_STD_VER >= 20 template <class _BiIter> -using __sub_match_cat = compare_three_way_result_t<basic_string<typename iterator_traits<_BiIter>::value_type>>; +using __sub_match_cat _LIBCPP_NODEBUG = + compare_three_way_result_t<basic_string<typename iterator_traits<_BiIter>::value_type>>; template <class _BiIter> _LIBCPP_HIDE_FROM_ABI auto operator<=>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) { diff --git a/libcxx/include/source_location b/libcxx/include/source_location index bbbb86bc68c8..b4777ce5a100 100644 --- a/libcxx/include/source_location +++ b/libcxx/include/source_location @@ -55,7 +55,7 @@ class source_location { // in constant evaluation, so we don't want to use `void*` as the argument // type unless the builtin returned that, anyhow, and the invalid cast is // unavoidable. - using __bsl_ty = decltype(__builtin_source_location()); + using __bsl_ty _LIBCPP_NODEBUG = decltype(__builtin_source_location()); public: // The defaulted __ptr argument is necessary so that the builtin is evaluated diff --git a/libcxx/include/string b/libcxx/include/string index 7808f56f6001..39982d5670bd 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -764,7 +764,7 @@ struct __padding<0> {}; template <class _CharT, class _Traits, class _Allocator> class basic_string { private: - using __default_allocator_type = allocator<_CharT>; + using __default_allocator_type _LIBCPP_NODEBUG = allocator<_CharT>; public: typedef basic_string __self; @@ -798,7 +798,7 @@ public: // Therefore it's crucial to ensure the destructor is called. using __trivially_relocatable = void; # else - using __trivially_relocatable = __conditional_t< + using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t< __libcpp_is_trivially_relocatable<allocator_type>::value && __libcpp_is_trivially_relocatable<pointer>::value, basic_string, void>; diff --git a/libcxx/include/tuple b/libcxx/include/tuple index b2478746f5e2..aca14ba408d3 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -552,7 +552,8 @@ class _LIBCPP_TEMPLATE_VIS tuple { get(const tuple<_Up...>&&) _NOEXCEPT; public: - using __trivially_relocatable = __conditional_t<_And<__libcpp_is_trivially_relocatable<_Tp>...>::value, tuple, void>; + using __trivially_relocatable _LIBCPP_NODEBUG = + __conditional_t<_And<__libcpp_is_trivially_relocatable<_Tp>...>::value, tuple, void>; // [tuple.cnstr] @@ -1125,9 +1126,9 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_T } template <class... _Tp> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<typename __unwrap_ref_decay<_Tp>::type...> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<__unwrap_ref_decay_t<_Tp>...> make_tuple(_Tp&&... __t) { - return tuple<typename __unwrap_ref_decay<_Tp>::type...>(std::forward<_Tp>(__t)...); + return tuple<__unwrap_ref_decay_t<_Tp>...>(std::forward<_Tp>(__t)...); } template <class... _Tp> diff --git a/libcxx/include/variant b/libcxx/include/variant index 3fa1b4b30f05..6c7be7f8f1eb 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -357,7 +357,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() { } template <size_t _NumAlts> -using __variant_index_t = decltype(std::__choose_index_type<_NumAlts>()); +using __variant_index_t _LIBCPP_NODEBUG = decltype(std::__choose_index_type<_NumAlts>()); template <class _IndexType> constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1); @@ -658,8 +658,8 @@ private: template <size_t _Index, class _Tp> struct _LIBCPP_TEMPLATE_VIS __alt { - using __value_type = _Tp; - static constexpr size_t __index = _Index; + using __value_type _LIBCPP_NODEBUG = _Tp; + static constexpr size_t __index = _Index; template <class... _Args> _LIBCPP_HIDE_FROM_ABI explicit constexpr __alt(in_place_t, _Args&&... __args) @@ -713,7 +713,7 @@ _LIBCPP_VARIANT_UNION(_Trait::_Unavailable, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTE template <_Trait _DestructibleTrait, class... _Types> class _LIBCPP_TEMPLATE_VIS __base { public: - using __index_t = __variant_index_t<sizeof...(_Types)>; + using __index_t _LIBCPP_NODEBUG = __variant_index_t<sizeof...(_Types)>; _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(__valueless_t __tag) noexcept : __data(__tag), __index(__variant_npos<__index_t>) {} @@ -753,8 +753,8 @@ class _LIBCPP_TEMPLATE_VIS __dtor; template <class... _Types> \ class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, destructible_trait> \ : public __base<destructible_trait, _Types...> { \ - using __base_type = __base<destructible_trait, _Types...>; \ - using __index_t = typename __base_type::__index_t; \ + using __base_type _LIBCPP_NODEBUG = __base<destructible_trait, _Types...>; \ + using __index_t _LIBCPP_NODEBUG = typename __base_type::__index_t; \ \ public: \ using __base_type::__base_type; \ @@ -799,7 +799,7 @@ _LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable, template <class _Traits> class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> { - using __base_type = __dtor<_Traits>; + using __base_type _LIBCPP_NODEBUG = __dtor<_Traits>; public: using __base_type::__base_type; @@ -831,7 +831,7 @@ class _LIBCPP_TEMPLATE_VIS __move_constructor; template <class... _Types> \ class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, move_constructible_trait> \ : public __ctor<__traits<_Types...>> { \ - using __base_type = __ctor<__traits<_Types...>>; \ + using __base_type _LIBCPP_NODEBUG = __ctor<__traits<_Types...>>; \ \ public: \ using __base_type::__base_type; \ @@ -869,7 +869,7 @@ class _LIBCPP_TEMPLATE_VIS __copy_constructor; template <class... _Types> \ class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, copy_constructible_trait> \ : public __move_constructor<__traits<_Types...>> { \ - using __base_type = __move_constructor<__traits<_Types...>>; \ + using __base_type _LIBCPP_NODEBUG = __move_constructor<__traits<_Types...>>; \ \ public: \ using __base_type::__base_type; \ @@ -899,7 +899,7 @@ _LIBCPP_VARIANT_COPY_CONSTRUCTOR( template <class _Traits> class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> { - using __base_type = __copy_constructor<_Traits>; + using __base_type _LIBCPP_NODEBUG = __copy_constructor<_Traits>; public: using __base_type::__base_type; @@ -958,7 +958,7 @@ class _LIBCPP_TEMPLATE_VIS __move_assignment; template <class... _Types> \ class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, move_assignable_trait> \ : public __assignment<__traits<_Types...>> { \ - using __base_type = __assignment<__traits<_Types...>>; \ + using __base_type _LIBCPP_NODEBUG = __assignment<__traits<_Types...>>; \ \ public: \ using __base_type::__base_type; \ @@ -997,7 +997,7 @@ class _LIBCPP_TEMPLATE_VIS __copy_assignment; template <class... _Types> \ class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, copy_assignable_trait> \ : public __move_assignment<__traits<_Types...>> { \ - using __base_type = __move_assignment<__traits<_Types...>>; \ + using __base_type _LIBCPP_NODEBUG = __move_assignment<__traits<_Types...>>; \ \ public: \ using __base_type::__base_type; \ @@ -1030,7 +1030,7 @@ _LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable, template <class... _Types> class _LIBCPP_TEMPLATE_VIS __impl : public __copy_assignment<__traits<_Types...>> { - using __base_type = __copy_assignment<__traits<_Types...>>; + using __base_type _LIBCPP_NODEBUG = __copy_assignment<__traits<_Types...>>; public: using __base_type::__base_type; // get in_place_index_t constructor & friends @@ -1097,7 +1097,7 @@ private: struct __no_narrowing_check { template <class _Dest, class _Source> - using _Apply = __type_identity<_Dest>; + using _Apply _LIBCPP_NODEBUG = __type_identity<_Dest>; }; struct __narrowing_check { @@ -1138,7 +1138,7 @@ using _MakeOverloads _LIBCPP_NODEBUG = typename __make_overloads_imp< __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>; template <class _Tp, class... _Types> -using __best_match_t = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type; +using __best_match_t _LIBCPP_NODEBUG = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type; } // namespace __variant_detail @@ -1170,10 +1170,10 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant static_assert(__all<!is_void_v<_Types>...>::value, "variant can not have a void type as an alternative."); - using __first_type = variant_alternative_t<0, variant>; + using __first_type _LIBCPP_NODEBUG = variant_alternative_t<0, variant>; public: - using __trivially_relocatable = + using __trivially_relocatable _LIBCPP_NODEBUG = conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>; template <bool _Dummy = true, diff --git a/libcxx/src/experimental/tzdb.cpp b/libcxx/src/experimental/tzdb.cpp index d22de21c9981..638d45f69e03 100644 --- a/libcxx/src/experimental/tzdb.cpp +++ b/libcxx/src/experimental/tzdb.cpp @@ -9,11 +9,14 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html #include <algorithm> +#include <cctype> #include <chrono> #include <filesystem> #include <fstream> #include <stdexcept> #include <string> +#include <string_view> +#include <vector> #include "include/tzdb/time_zone_private.h" #include "include/tzdb/types_private.h" diff --git a/libcxx/src/filesystem/directory_iterator.cpp b/libcxx/src/filesystem/directory_iterator.cpp index d7ed9a358f55..7e8e40d17f7a 100644 --- a/libcxx/src/filesystem/directory_iterator.cpp +++ b/libcxx/src/filesystem/directory_iterator.cpp @@ -47,9 +47,9 @@ public: } __stream_ = ::FindFirstFileW((root / "*").c_str(), &__data_); if (__stream_ == INVALID_HANDLE_VALUE) { - ec = detail::make_windows_error(GetLastError()); + ec = detail::get_last_error(); const bool ignore_permission_denied = bool(opts & directory_options::skip_permission_denied); - if (ignore_permission_denied && ec.value() == static_cast<int>(errc::permission_denied)) + if (ignore_permission_denied && ec == errc::permission_denied) ec.clear(); return; } @@ -91,7 +91,7 @@ private: error_code close() noexcept { error_code ec; if (!::FindClose(__stream_)) - ec = detail::make_windows_error(GetLastError()); + ec = detail::get_last_error(); __stream_ = INVALID_HANDLE_VALUE; return ec; } @@ -118,7 +118,7 @@ public: if ((__stream_ = ::opendir(root.c_str())) == nullptr) { ec = detail::capture_errno(); const bool allow_eacces = bool(opts & directory_options::skip_permission_denied); - if (allow_eacces && ec.value() == EACCES) + if (allow_eacces && ec == errc::permission_denied) ec.clear(); return; } @@ -307,7 +307,7 @@ bool recursive_directory_iterator::__try_recursion(error_code* ec) { } if (m_ec) { const bool allow_eacess = bool(__imp_->__options_ & directory_options::skip_permission_denied); - if (m_ec.value() == EACCES && allow_eacess) { + if (m_ec == errc::permission_denied && allow_eacess) { if (ec) ec->clear(); } else { diff --git a/libcxx/src/filesystem/error.h b/libcxx/src/filesystem/error.h index 07ba7fc3eef2..c0213910b378 100644 --- a/libcxx/src/filesystem/error.h +++ b/libcxx/src/filesystem/error.h @@ -32,80 +32,21 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM namespace detail { -#if defined(_LIBCPP_WIN32API) - -inline errc __win_err_to_errc(int err) { - constexpr struct { - DWORD win; - errc errc; - } win_error_mapping[] = { - {ERROR_ACCESS_DENIED, errc::permission_denied}, - {ERROR_ALREADY_EXISTS, errc::file_exists}, - {ERROR_BAD_NETPATH, errc::no_such_file_or_directory}, - {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory}, - {ERROR_BAD_UNIT, errc::no_such_device}, - {ERROR_BROKEN_PIPE, errc::broken_pipe}, - {ERROR_BUFFER_OVERFLOW, errc::filename_too_long}, - {ERROR_BUSY, errc::device_or_resource_busy}, - {ERROR_BUSY_DRIVE, errc::device_or_resource_busy}, - {ERROR_CANNOT_MAKE, errc::permission_denied}, - {ERROR_CANTOPEN, errc::io_error}, - {ERROR_CANTREAD, errc::io_error}, - {ERROR_CANTWRITE, errc::io_error}, - {ERROR_CURRENT_DIRECTORY, errc::permission_denied}, - {ERROR_DEV_NOT_EXIST, errc::no_such_device}, - {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy}, - {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty}, - {ERROR_DIRECTORY, errc::invalid_argument}, - {ERROR_DISK_FULL, errc::no_space_on_device}, - {ERROR_FILE_EXISTS, errc::file_exists}, - {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory}, - {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device}, - {ERROR_INVALID_ACCESS, errc::permission_denied}, - {ERROR_INVALID_DRIVE, errc::no_such_device}, - {ERROR_INVALID_FUNCTION, errc::function_not_supported}, - {ERROR_INVALID_HANDLE, errc::invalid_argument}, - {ERROR_INVALID_NAME, errc::no_such_file_or_directory}, - {ERROR_INVALID_PARAMETER, errc::invalid_argument}, - {ERROR_LOCK_VIOLATION, errc::no_lock_available}, - {ERROR_LOCKED, errc::no_lock_available}, - {ERROR_NEGATIVE_SEEK, errc::invalid_argument}, - {ERROR_NOACCESS, errc::permission_denied}, - {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory}, - {ERROR_NOT_READY, errc::resource_unavailable_try_again}, - {ERROR_NOT_SAME_DEVICE, errc::cross_device_link}, - {ERROR_NOT_SUPPORTED, errc::not_supported}, - {ERROR_OPEN_FAILED, errc::io_error}, - {ERROR_OPEN_FILES, errc::device_or_resource_busy}, - {ERROR_OPERATION_ABORTED, errc::operation_canceled}, - {ERROR_OUTOFMEMORY, errc::not_enough_memory}, - {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory}, - {ERROR_READ_FAULT, errc::io_error}, - {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument}, - {ERROR_RETRY, errc::resource_unavailable_try_again}, - {ERROR_SEEK, errc::io_error}, - {ERROR_SHARING_VIOLATION, errc::permission_denied}, - {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open}, - {ERROR_WRITE_FAULT, errc::io_error}, - {ERROR_WRITE_PROTECT, errc::permission_denied}, - }; - - for (const auto& pair : win_error_mapping) - if (pair.win == static_cast<DWORD>(err)) - return pair.errc; - return errc::invalid_argument; -} - -#endif // _LIBCPP_WIN32API +// On windows, libc functions use errno, but system functions use GetLastError. +// So, callers need to be careful which of these next functions they call! inline error_code capture_errno() { _LIBCPP_ASSERT_INTERNAL(errno != 0, "Expected errno to be non-zero"); return error_code(errno, generic_category()); } +inline error_code get_last_error() { #if defined(_LIBCPP_WIN32API) -inline error_code make_windows_error(int err) { return make_error_code(__win_err_to_errc(err)); } + return std::error_code(GetLastError(), std::system_category()); +#else + return capture_errno(); #endif +} template <class T> T error_value(); diff --git a/libcxx/src/filesystem/file_descriptor.h b/libcxx/src/filesystem/file_descriptor.h index db66ad55bd4f..9c279c451f28 100644 --- a/libcxx/src/filesystem/file_descriptor.h +++ b/libcxx/src/filesystem/file_descriptor.h @@ -201,7 +201,7 @@ inline perms posix_get_perms(const StatT& st) noexcept { return static_cast<perm inline file_status create_file_status(error_code& m_ec, path const& p, const StatT& path_stat, error_code* ec) { if (ec) *ec = m_ec; - if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) { + if (m_ec && (m_ec == errc::no_such_file_or_directory || m_ec == errc::not_a_directory)) { return file_status(file_type::not_found); } else if (m_ec) { ErrorHandler<void> err("posix_stat", ec, &p); @@ -236,7 +236,7 @@ inline file_status create_file_status(error_code& m_ec, path const& p, const Sta inline file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) { error_code m_ec; if (detail::stat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); + m_ec = detail::get_last_error(); return create_file_status(m_ec, p, path_stat, ec); } @@ -248,7 +248,7 @@ inline file_status posix_stat(path const& p, error_code* ec) { inline file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) { error_code m_ec; if (detail::lstat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); + m_ec = detail::get_last_error(); return create_file_status(m_ec, p, path_stat, ec); } @@ -260,7 +260,7 @@ inline file_status posix_lstat(path const& p, error_code* ec) { // http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) { if (detail::ftruncate(fd.fd, to_size) == -1) { - ec = capture_errno(); + ec = get_last_error(); return true; } ec.clear(); @@ -269,7 +269,7 @@ inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& inline bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) { if (detail::fchmod(fd.fd, st.st_mode) == -1) { - ec = capture_errno(); + ec = get_last_error(); return true; } ec.clear(); @@ -286,7 +286,7 @@ inline file_status FileDescriptor::refresh_status(error_code& ec) { m_stat = {}; error_code m_ec; if (detail::fstat(fd, &m_stat) == -1) - m_ec = capture_errno(); + m_ec = get_last_error(); m_status = create_file_status(m_ec, name, m_stat, &ec); return m_status; } diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp index d771f2009735..23c1c281ba1c 100644 --- a/libcxx/src/filesystem/operations.cpp +++ b/libcxx/src/filesystem/operations.cpp @@ -15,6 +15,7 @@ #include <filesystem> #include <iterator> #include <string_view> +#include <system_error> #include <type_traits> #include <vector> @@ -32,11 +33,24 @@ # include <dirent.h> # include <sys/stat.h> # include <sys/statvfs.h> +# include <sys/types.h> # include <unistd.h> #endif #include <fcntl.h> /* values for fchmodat */ #include <time.h> +// since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc >= 2.27 and musl +#if defined(__linux__) +# if defined(_LIBCPP_GLIBC_PREREQ) +# if _LIBCPP_GLIBC_PREREQ(2, 27) +# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE +# endif +# elif _LIBCPP_HAS_MUSL_LIBC +# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE +# endif +#elif defined(__FreeBSD__) +# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE +#endif #if __has_include(<sys/sendfile.h>) # include <sys/sendfile.h> # define _LIBCPP_FILESYSTEM_USE_SENDFILE @@ -44,10 +58,18 @@ # include <copyfile.h> # define _LIBCPP_FILESYSTEM_USE_COPYFILE #else -# include <fstream> # define _LIBCPP_FILESYSTEM_USE_FSTREAM #endif +// sendfile and copy_file_range need to fall back +// to the fstream implementation for special files +#if (defined(_LIBCPP_FILESYSTEM_USE_SENDFILE) || defined(_LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE) || \ + defined(_LIBCPP_FILESYSTEM_USE_FSTREAM)) && \ + _LIBCPP_HAS_LOCALIZATION +# include <fstream> +# define _LIBCPP_FILESYSTEM_NEED_FSTREAM +#endif + #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) # pragma comment(lib, "rt") #endif @@ -86,7 +108,7 @@ path __canonical(path const& orig_p, error_code* ec) { #if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112) || defined(_LIBCPP_WIN32API) std::unique_ptr<path::value_type, decltype(&::free)> hold(detail::realpath(p.c_str(), nullptr), &::free); if (hold.get() == nullptr) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); return {hold.get()}; #else # if defined(__MVS__) && !defined(PATH_MAX) @@ -96,7 +118,7 @@ path __canonical(path const& orig_p, error_code* ec) { # endif path::value_type* ret; if ((ret = detail::realpath(p.c_str(), buff)) == nullptr) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); return {ret}; #endif } @@ -178,9 +200,89 @@ void __copy(const path& from, const path& to, copy_options options, error_code* namespace detail { namespace { +#if defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM) +bool copy_file_impl_fstream(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { + ifstream in; + in.__open(read_fd.fd, ios::binary); + if (!in.is_open()) { + // This assumes that __open didn't reset the error code. + ec = capture_errno(); + return false; + } + read_fd.fd = -1; + ofstream out; + out.__open(write_fd.fd, ios::binary); + if (!out.is_open()) { + ec = capture_errno(); + return false; + } + write_fd.fd = -1; + + if (in.good() && out.good()) { + using InIt = istreambuf_iterator<char>; + using OutIt = ostreambuf_iterator<char>; + InIt bin(in); + InIt ein; + OutIt bout(out); + copy(bin, ein, bout); + } + if (out.fail() || in.fail()) { + ec = make_error_code(errc::io_error); + return false; + } + + ec.clear(); + return true; +} +#endif + +#if defined(_LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE) +bool copy_file_impl_copy_file_range(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { + size_t count = read_fd.get_stat().st_size; + // a zero-length file is either empty, or not copyable by this syscall + // return early to avoid the syscall cost + if (count == 0) { + ec = {EINVAL, generic_category()}; + return false; + } + // do not modify the fd positions as copy_file_impl_sendfile may be called after a partial copy +# if defined(__linux__) + loff_t off_in = 0; + loff_t off_out = 0; +# else + off_t off_in = 0; + off_t off_out = 0; +# endif + + do { + ssize_t res; + + if ((res = ::copy_file_range(read_fd.fd, &off_in, write_fd.fd, &off_out, count, 0)) == -1) { + ec = capture_errno(); + return false; + } + count -= res; + } while (count > 0); + + ec.clear(); + + return true; +} +#endif + #if defined(_LIBCPP_FILESYSTEM_USE_SENDFILE) -bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { +bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { size_t count = read_fd.get_stat().st_size; + // a zero-length file is either empty, or not copyable by this syscall + // return early to avoid the syscall cost + // however, we can't afford this luxury in the no-locale build, + // as we can't utilize the fstream impl to copy empty files +# if _LIBCPP_HAS_LOCALIZATION + if (count == 0) { + ec = {EINVAL, generic_category()}; + return false; + } +# endif do { ssize_t res; if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) { @@ -194,6 +296,54 @@ bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_cod return true; } +#endif + +#if defined(_LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE) || defined(_LIBCPP_FILESYSTEM_USE_SENDFILE) +// If we have copy_file_range or sendfile, try both in succession (if available). +// If both fail, fall back to using fstream. +bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { +# if defined(_LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE) + if (copy_file_impl_copy_file_range(read_fd, write_fd, ec)) { + return true; + } + // EINVAL: src and dst are the same file (this is not cheaply + // detectable from userspace) + // EINVAL: copy_file_range is unsupported for this file type by the + // underlying filesystem + // ENOTSUP: undocumented, can arise with old kernels and NFS + // EOPNOTSUPP: filesystem does not implement copy_file_range + // ETXTBSY: src or dst is an active swapfile (nonsensical, but allowed + // with normal copying) + // EXDEV: src and dst are on different filesystems that do not support + // cross-fs copy_file_range + // ENOENT: undocumented, can arise with CIFS + // ENOSYS: unsupported by kernel or blocked by seccomp + if (ec.value() != EINVAL && ec.value() != ENOTSUP && ec.value() != EOPNOTSUPP && ec.value() != ETXTBSY && + ec.value() != EXDEV && ec.value() != ENOENT && ec.value() != ENOSYS) { + return false; + } + ec.clear(); +# endif + +# if defined(_LIBCPP_FILESYSTEM_USE_SENDFILE) + if (copy_file_impl_sendfile(read_fd, write_fd, ec)) { + return true; + } + // EINVAL: unsupported file type + if (ec.value() != EINVAL) { + return false; + } + ec.clear(); +# endif + +# if defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM) + return copy_file_impl_fstream(read_fd, write_fd, ec); +# else + // since iostreams are unavailable in the no-locale build, just fail after a failed sendfile + ec.assign(EINVAL, std::system_category()); + return false; +# endif +} #elif defined(_LIBCPP_FILESYSTEM_USE_COPYFILE) bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { struct CopyFileState { @@ -217,37 +367,7 @@ bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_cod } #elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM) bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { - ifstream in; - in.__open(read_fd.fd, ios::binary); - if (!in.is_open()) { - // This assumes that __open didn't reset the error code. - ec = capture_errno(); - return false; - } - read_fd.fd = -1; - ofstream out; - out.__open(write_fd.fd, ios::binary); - if (!out.is_open()) { - ec = capture_errno(); - return false; - } - write_fd.fd = -1; - - if (in.good() && out.good()) { - using InIt = istreambuf_iterator<char>; - using OutIt = ostreambuf_iterator<char>; - InIt bin(in); - InIt ein; - OutIt bout(out); - copy(bin, ein, bout); - } - if (out.fail() || in.fail()) { - ec = make_error_code(errc::io_error); - return false; - } - - ec.clear(); - return true; + return copy_file_impl_fstream(read_fd, write_fd, ec); } #else # error "Unknown implementation for copy_file_impl" @@ -393,9 +513,9 @@ bool __create_directory(const path& p, error_code* ec) { if (detail::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0) return true; - if (errno != EEXIST) - return err.report(capture_errno()); - error_code mec = capture_errno(); + error_code mec = detail::get_last_error(); + if (mec != errc::file_exists) + return err.report(mec); error_code ignored_ec; const file_status st = status(p, ignored_ec); if (!is_directory(st)) @@ -417,10 +537,10 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) { if (detail::mkdir(p.c_str(), attr_stat.st_mode) == 0) return true; - if (errno != EEXIST) - return err.report(capture_errno()); + mec = detail::get_last_error(); + if (mec != errc::file_exists) + return err.report(mec); - mec = capture_errno(); error_code ignored_ec; st = status(p, ignored_ec); if (!is_directory(st)) @@ -431,19 +551,19 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) { void __create_directory_symlink(path const& from, path const& to, error_code* ec) { ErrorHandler<void> err("create_directory_symlink", ec, &from, &to); if (detail::symlink_dir(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } void __create_hard_link(const path& from, const path& to, error_code* ec) { ErrorHandler<void> err("create_hard_link", ec, &from, &to); if (detail::link(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } void __create_symlink(path const& from, path const& to, error_code* ec) { ErrorHandler<void> err("create_symlink", ec, &from, &to); if (detail::symlink_file(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } path __current_path(error_code* ec) { @@ -486,7 +606,7 @@ path __current_path(error_code* ec) { unique_ptr<path::value_type, Deleter> hold(detail::getcwd(ptr, size), deleter); if (hold.get() == nullptr) - return err.report(capture_errno(), "call to getcwd failed"); + return err.report(detail::get_last_error(), "call to getcwd failed"); return {hold.get()}; } @@ -494,7 +614,7 @@ path __current_path(error_code* ec) { void __current_path(const path& p, error_code* ec) { ErrorHandler<void> err("current_path", ec, &p); if (detail::chdir(p.c_str()) == -1) - err.report(capture_errno()); + err.report(detail::get_last_error()); } bool __equivalent(const path& p1, const path& p2, error_code* ec) { @@ -582,10 +702,10 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) { return err.report(errc::value_too_large); detail::WinHandle h(p.c_str(), FILE_WRITE_ATTRIBUTES, 0); if (!h) - return err.report(detail::make_windows_error(GetLastError())); + return err.report(detail::get_last_error()); FILETIME last_write = timespec_to_filetime(ts); if (!SetFileTime(h, nullptr, nullptr, &last_write)) - return err.report(detail::make_windows_error(GetLastError())); + return err.report(detail::get_last_error()); #else error_code m_ec; array<TimeSpec, 2> tbuf; @@ -643,7 +763,7 @@ void __permissions(const path& p, perms prms, perm_options opts, error_code* ec) #if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0; if (detail::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) { - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } #else if (set_sym_perms) @@ -671,14 +791,14 @@ path __read_symlink(const path& p, error_code* ec) { #else StatT sb; if (detail::lstat(p.c_str(), &sb) == -1) { - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } const size_t size = sb.st_size + 1; auto buff = unique_ptr<path::value_type[]>(new path::value_type[size]); #endif detail::SSizeT ret; if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); // Note that `ret` returning `0` would work, resulting in a valid empty string being returned. if (static_cast<size_t>(ret) >= size) return err.report(errc::value_too_large); @@ -689,8 +809,9 @@ path __read_symlink(const path& p, error_code* ec) { bool __remove(const path& p, error_code* ec) { ErrorHandler<bool> err("remove", ec, &p); if (detail::remove(p.c_str()) == -1) { - if (errno != ENOENT) - err.report(capture_errno()); + error_code mec = detail::get_last_error(); + if (mec != errc::no_such_file_or_directory) + err.report(mec); return false; } return true; @@ -843,13 +964,13 @@ uintmax_t __remove_all(const path& p, error_code* ec) { void __rename(const path& from, const path& to, error_code* ec) { ErrorHandler<void> err("rename", ec, &from, &to); if (detail::rename(from.c_str(), to.c_str()) == -1) - err.report(capture_errno()); + err.report(detail::get_last_error()); } void __resize_file(const path& p, uintmax_t size, error_code* ec) { ErrorHandler<void> err("resize_file", ec, &p); if (detail::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1) - return err.report(capture_errno()); + return err.report(detail::get_last_error()); } space_info __space(const path& p, error_code* ec) { @@ -857,7 +978,7 @@ space_info __space(const path& p, error_code* ec) { space_info si; detail::StatVFS m_svfs = {}; if (detail::statvfs(p.c_str(), &m_svfs) == -1) { - err.report(capture_errno()); + err.report(detail::get_last_error()); si.capacity = si.free = si.available = static_cast<uintmax_t>(-1); return si; } @@ -884,7 +1005,7 @@ path __temp_directory_path(error_code* ec) { wchar_t buf[MAX_PATH]; DWORD retval = GetTempPathW(MAX_PATH, buf); if (!retval) - return err.report(detail::make_windows_error(GetLastError())); + return err.report(detail::get_last_error()); if (retval > MAX_PATH) return err.report(errc::filename_too_long); // GetTempPathW returns a path with a trailing slash, which we diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h index b41c004341af..ddd99d8aaf20 100644 --- a/libcxx/src/filesystem/posix_compat.h +++ b/libcxx/src/filesystem/posix_compat.h @@ -11,9 +11,10 @@ // // These generally behave like the proper posix functions, with these // exceptions: -// On Windows, they take paths in wchar_t* form, instead of char* form. -// The symlink() function is split into two frontends, symlink_file() -// and symlink_dir(). +// - On Windows, they take paths in wchar_t* form, instead of char* form. +// - The symlink() function is split into two frontends, symlink_file() +// and symlink_dir(). +// - Errors should be retrieved with get_last_error, not errno. // // These are provided within an anonymous namespace within the detail // namespace - callers need to include this header and call them as @@ -122,11 +123,6 @@ namespace detail { # define O_NONBLOCK 0 -inline int set_errno(int e = GetLastError()) { - errno = static_cast<int>(__win_err_to_errc(e)); - return -1; -} - class WinHandle { public: WinHandle(const wchar_t* p, DWORD access, DWORD flags) { @@ -153,7 +149,7 @@ private: inline int stat_handle(HANDLE h, StatT* buf) { FILE_BASIC_INFO basic; if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) - return set_errno(); + return -1; memset(buf, 0, sizeof(*buf)); buf->st_mtim = filetime_to_timespec(basic.LastWriteTime); buf->st_atim = filetime_to_timespec(basic.LastAccessTime); @@ -168,18 +164,18 @@ inline int stat_handle(HANDLE h, StatT* buf) { if (basic.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { FILE_ATTRIBUTE_TAG_INFO tag; if (!GetFileInformationByHandleEx(h, FileAttributeTagInfo, &tag, sizeof(tag))) - return set_errno(); + return -1; if (tag.ReparseTag == IO_REPARSE_TAG_SYMLINK) buf->st_mode = (buf->st_mode & ~_S_IFMT) | _S_IFLNK; } FILE_STANDARD_INFO standard; if (!GetFileInformationByHandleEx(h, FileStandardInfo, &standard, sizeof(standard))) - return set_errno(); + return -1; buf->st_nlink = standard.NumberOfLinks; buf->st_size = standard.EndOfFile.QuadPart; BY_HANDLE_FILE_INFORMATION info; if (!GetFileInformationByHandle(h, &info)) - return set_errno(); + return -1; buf->st_dev = info.dwVolumeSerialNumber; memcpy(&buf->st_ino.id[0], &info.nFileIndexHigh, 4); memcpy(&buf->st_ino.id[4], &info.nFileIndexLow, 4); @@ -189,7 +185,7 @@ inline int stat_handle(HANDLE h, StatT* buf) { inline int stat_file(const wchar_t* path, StatT* buf, DWORD flags) { WinHandle h(path, FILE_READ_ATTRIBUTES, flags); if (!h) - return set_errno(); + return -1; int ret = stat_handle(h, buf); return ret; } @@ -206,7 +202,7 @@ inline int fstat(int fd, StatT* buf) { inline int mkdir(const wchar_t* path, int permissions) { (void)permissions; if (!CreateDirectoryW(path, nullptr)) - return set_errno(); + return -1; return 0; } @@ -219,10 +215,10 @@ inline int symlink_file_dir(const wchar_t* oldname, const wchar_t* newname, bool return 0; int e = GetLastError(); if (e != ERROR_INVALID_PARAMETER) - return set_errno(e); + return -1; if (CreateSymbolicLinkW(newname, oldname, flags)) return 0; - return set_errno(); + return -1; } inline int symlink_file(const wchar_t* oldname, const wchar_t* newname) { @@ -236,17 +232,17 @@ inline int symlink_dir(const wchar_t* oldname, const wchar_t* newname) { inline int link(const wchar_t* oldname, const wchar_t* newname) { if (CreateHardLinkW(newname, oldname, nullptr)) return 0; - return set_errno(); + return -1; } inline int remove(const wchar_t* path) { detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT); if (!h) - return set_errno(); + return -1; FILE_DISPOSITION_INFO info; info.DeleteFile = TRUE; if (!SetFileInformationByHandle(h, FileDispositionInfo, &info, sizeof(info))) - return set_errno(); + return -1; return 0; } @@ -254,9 +250,9 @@ inline int truncate_handle(HANDLE h, off_t length) { LARGE_INTEGER size_param; size_param.QuadPart = length; if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN)) - return set_errno(); + return -1; if (!SetEndOfFile(h)) - return set_errno(); + return -1; return 0; } @@ -268,19 +264,19 @@ inline int ftruncate(int fd, off_t length) { inline int truncate(const wchar_t* path, off_t length) { detail::WinHandle h(path, GENERIC_WRITE, 0); if (!h) - return set_errno(); + return -1; return truncate_handle(h, length); } inline int rename(const wchar_t* from, const wchar_t* to) { if (!(MoveFileExW(from, to, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))) - return set_errno(); + return -1; return 0; } inline int chdir(const wchar_t* path) { if (!SetCurrentDirectoryW(path)) - return set_errno(); + return -1; return 0; } @@ -300,7 +296,7 @@ inline int statvfs(const wchar_t* p, StatVFS* buf) { break; path parent = dir.parent_path(); if (parent == dir) { - errno = ENOENT; + SetLastError(ERROR_PATH_NOT_FOUND); return -1; } dir = parent; @@ -308,7 +304,7 @@ inline int statvfs(const wchar_t* p, StatVFS* buf) { ULARGE_INTEGER free_bytes_available_to_caller, total_number_of_bytes, total_number_of_free_bytes; if (!GetDiskFreeSpaceExW( dir.c_str(), &free_bytes_available_to_caller, &total_number_of_bytes, &total_number_of_free_bytes)) - return set_errno(); + return -1; buf->f_frsize = 1; buf->f_blocks = total_number_of_bytes.QuadPart; buf->f_bfree = total_number_of_free_bytes.QuadPart; @@ -330,7 +326,6 @@ inline wchar_t* getcwd([[maybe_unused]] wchar_t* in_buf, [[maybe_unused]] size_t retval = GetCurrentDirectoryW(buff_size, buff.get()); } if (!retval) { - set_errno(); return nullptr; } return buff.release(); @@ -342,7 +337,6 @@ inline wchar_t* realpath(const wchar_t* path, [[maybe_unused]] wchar_t* resolved WinHandle h(path, FILE_READ_ATTRIBUTES, 0); if (!h) { - set_errno(); return nullptr; } size_t buff_size = MAX_PATH + 10; @@ -354,7 +348,6 @@ inline wchar_t* realpath(const wchar_t* path, [[maybe_unused]] wchar_t* resolved retval = GetFinalPathNameByHandleW(h, buff.get(), buff_size, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); } if (!retval) { - set_errno(); return nullptr; } wchar_t* ptr = buff.get(); @@ -376,20 +369,20 @@ using ModeT = int; inline int fchmod_handle(HANDLE h, int perms) { FILE_BASIC_INFO basic; if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) - return set_errno(); + return -1; DWORD orig_attributes = basic.FileAttributes; basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; if ((perms & 0222) == 0) basic.FileAttributes |= FILE_ATTRIBUTE_READONLY; if (basic.FileAttributes != orig_attributes && !SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic))) - return set_errno(); + return -1; return 0; } inline int fchmodat(int /*fd*/, const wchar_t* path, int perms, int flag) { DWORD attributes = GetFileAttributesW(path); if (attributes == INVALID_FILE_ATTRIBUTES) - return set_errno(); + return -1; if (attributes & FILE_ATTRIBUTE_REPARSE_POINT && !(flag & AT_SYMLINK_NOFOLLOW)) { // If the file is a symlink, and we are supposed to operate on the target // of the symlink, we need to open a handle to it, without the @@ -397,7 +390,7 @@ inline int fchmodat(int /*fd*/, const wchar_t* path, int perms, int flag) { // symlink, and operate on it via the handle. detail::WinHandle h(path, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, 0); if (!h) - return set_errno(); + return -1; return fchmod_handle(h, perms); } else { // For a non-symlink, or if operating on the symlink itself instead of @@ -407,7 +400,7 @@ inline int fchmodat(int /*fd*/, const wchar_t* path, int perms, int flag) { if ((perms & 0222) == 0) attributes |= FILE_ATTRIBUTE_READONLY; if (attributes != orig_attributes && !SetFileAttributesW(path, attributes)) - return set_errno(); + return -1; } return 0; } @@ -424,18 +417,18 @@ inline SSizeT readlink(const wchar_t* path, wchar_t* ret_buf, size_t bufsize) { uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT); if (!h) - return set_errno(); + return -1; DWORD out; if (!DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, nullptr, 0, buf, sizeof(buf), &out, 0)) - return set_errno(); + return -1; const auto* reparse = reinterpret_cast<LIBCPP_REPARSE_DATA_BUFFER*>(buf); size_t path_buf_offset = offsetof(LIBCPP_REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0]); if (out < path_buf_offset) { - errno = EINVAL; + SetLastError(ERROR_REPARSE_TAG_INVALID); return -1; } if (reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) { - errno = EINVAL; + SetLastError(ERROR_REPARSE_TAG_INVALID); return -1; } const auto& symlink = reparse->SymbolicLinkReparseBuffer; @@ -449,11 +442,11 @@ inline SSizeT readlink(const wchar_t* path, wchar_t* ret_buf, size_t bufsize) { } // name_offset/length are expressed in bytes, not in wchar_t if (path_buf_offset + name_offset + name_length > out) { - errno = EINVAL; + SetLastError(ERROR_REPARSE_TAG_INVALID); return -1; } if (name_length / sizeof(wchar_t) > bufsize) { - errno = ENOMEM; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); return -1; } memcpy(ret_buf, &symlink.PathBuffer[name_offset / sizeof(wchar_t)], name_length); diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h index 6c70f6242ddd..7372e347831b 100644 --- a/libcxx/src/include/overridable_function.h +++ b/libcxx/src/include/overridable_function.h @@ -29,106 +29,81 @@ // This is a low-level utility which does not work on all platforms, since it needs // to make assumptions about the object file format in use. Furthermore, it requires // the "base definition" of the function (the one we want to check whether it has been -// overridden) to be annotated with the _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro. +// overridden) to be defined using the _LIBCPP_OVERRIDABLE_FUNCTION macro. // // This currently works with Mach-O files (used on Darwin) and with ELF files (used on Linux // and others). On platforms where we know how to implement this detection, the macro // _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION is defined to 1, and it is defined to 0 on -// other platforms. The _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro is defined to -// nothing on unsupported platforms so that it can be used to decorate functions regardless -// of whether detection is actually supported. +// other platforms. The _LIBCPP_OVERRIDABLE_FUNCTION macro expands to regular function +// definition on unsupported platforms so that it can be used to decorate functions +// regardless of whether detection is actually supported. // // How does this work? // ------------------- // // Let's say we want to check whether a weak function `f` has been overridden by the user. -// The general mechanism works by placing `f`'s definition (in the libc++ built library) -// inside a special section, which we do using the `__section__` attribute via the -// _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro. +// The general mechanism works by defining a symbol `f_impl__` and a weak alias `f` via the +// _LIBCPP_OVERRIDABLE_FUNCTION macro. // // Then, when comes the time to check whether the function has been overridden, we take -// the address of the function and we check whether it falls inside the special function -// we created. This can be done by finding pointers to the start and the end of the section -// (which is done differently for ELF and Mach-O), and then checking whether `f` falls -// within those bounds. If it falls within those bounds, then `f` is still inside the -// special section and so it is the version we defined in the libc++ built library, i.e. -// it was not overridden. Otherwise, it was overridden by the user because it falls -// outside of the section. +// the address of the function `f` and we check whether it is different from `f_impl__`. +// If so it means the function was overriden by the user. // // Important note // -------------- // -// This mechanism should never be used outside of the libc++ built library. In particular, -// attempting to use this within the libc++ headers will not work at all because we don't -// want to be defining special sections inside user's executables which use our headers. +// This mechanism should never be used outside of the libc++ built library. Functions defined +// with this macro must be defined at global scope. // #if defined(_LIBCPP_OBJECT_FORMAT_MACHO) -# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 -# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE \ - __attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions"))) - _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Ret, class... _Args> -_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept { - // Declare two dummy bytes and give them these special `__asm` values. These values are - // defined by the linker, which means that referring to `&__lcxx_override_start` will - // effectively refer to the address where the section starts (and same for the end). - extern char __lcxx_override_start __asm("section$start$__TEXT$__lcxx_override"); - extern char __lcxx_override_end __asm("section$end$__TEXT$__lcxx_override"); - - // Now get a uintptr_t out of these locations, and out of the function pointer. - uintptr_t __start = reinterpret_cast<uintptr_t>(&__lcxx_override_start); - uintptr_t __end = reinterpret_cast<uintptr_t>(&__lcxx_override_end); - uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr); - -# if __has_feature(ptrauth_calls) - // We must pass a void* to ptrauth_strip since it only accepts a pointer type. Also, in particular, - // we must NOT pass a function pointer, otherwise we will strip the function pointer, and then attempt - // to authenticate and re-sign it when casting it to a uintptr_t again, which will fail because we just - // stripped the function pointer. See rdar://122927845. - __ptr = reinterpret_cast<uintptr_t>(ptrauth_strip(reinterpret_cast<void*>(__ptr), ptrauth_key_function_pointer)); -# endif - - // Finally, the function was overridden if it falls outside of the section's bounds. - return __ptr < __start || __ptr > __end; -} -_LIBCPP_END_NAMESPACE_STD -// The NVPTX linker cannot create '__start/__stop' sections. -#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(__NVPTX__) +template <auto _Func> +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_function_overridden(); -# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 -# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE __attribute__((__section__("__lcxx_override"))) +_LIBCPP_END_NAMESPACE_STD -// This is very similar to what we do for Mach-O above. The ELF linker will implicitly define -// variables with those names corresponding to the start and the end of the section. -// -// See https://stackoverflow.com/questions/16552710/how-do-you-get-the-start-and-end-addresses-of-a-custom-elf-section -extern char __start___lcxx_override; -extern char __stop___lcxx_override; +# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 +# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \ + static __attribute__((used)) type symbol##_impl__ arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \ + __asm__(".globl _" _LIBCPP_TOSTRING(symbol)); \ + __asm__(".weak_definition _" _LIBCPP_TOSTRING(symbol)); \ + extern __typeof(symbol##_impl__) name __attribute__((weak_import)); \ + _LIBCPP_BEGIN_NAMESPACE_STD \ + template <> \ + inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \ + return static_cast<type(*) arglist>(name) != symbol##_impl__; \ + } \ + _LIBCPP_END_NAMESPACE_STD \ + static type symbol##_impl__ arglist + +#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Ret, class... _Args> -_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept { - uintptr_t __start = reinterpret_cast<uintptr_t>(&__start___lcxx_override); - uintptr_t __end = reinterpret_cast<uintptr_t>(&__stop___lcxx_override); - uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr); - -# if __has_feature(ptrauth_calls) - // We must pass a void* to ptrauth_strip since it only accepts a pointer type. See full explanation above. - __ptr = reinterpret_cast<uintptr_t>(ptrauth_strip(reinterpret_cast<void*>(__ptr), ptrauth_key_function_pointer)); -# endif - - return __ptr < __start || __ptr > __end; -} + +template <auto _Func> +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_function_overridden(); + _LIBCPP_END_NAMESPACE_STD +# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 +# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \ + static type symbol##_impl__ arglist __asm__(_LIBCPP_TOSTRING(symbol##_impl__)); \ + [[gnu::weak, gnu::alias(_LIBCPP_TOSTRING(symbol##_impl__))]] type name arglist; \ + _LIBCPP_BEGIN_NAMESPACE_STD \ + template <> \ + inline bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \ + return static_cast<type(*) arglist>(name) != symbol##_impl__; \ + } \ + _LIBCPP_END_NAMESPACE_STD \ + static type symbol##_impl__ arglist + #else # define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0 -# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE /* nothing */ +# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) _LIBCPP_WEAK type name arglist #endif diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp index e010fe4c4f19..b14b52248df3 100644 --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -43,7 +43,7 @@ static void* operator_new_impl(std::size_t size) { return p; } -_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { +_LIBCPP_OVERRIDABLE_FUNCTION(_Znwm, void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC { void* p = operator_new_impl(size); if (p == nullptr) __throw_bad_alloc_shim(); @@ -54,7 +54,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { # if !_LIBCPP_HAS_EXCEPTIONS # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION _LIBCPP_ASSERT_SHIM( - !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)), + !std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new)>(), "libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, " "but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because " "`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case " @@ -74,7 +74,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { # endif } -_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC { +_LIBCPP_OVERRIDABLE_FUNCTION(_Znam, void*, operator new[], (size_t size)) _THROW_BAD_ALLOC { return ::operator new(size); } @@ -82,7 +82,7 @@ _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept { # if !_LIBCPP_HAS_EXCEPTIONS # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION _LIBCPP_ASSERT_SHIM( - !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])), + !std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new[])>(), "libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, " "but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because " "`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case " @@ -136,8 +136,8 @@ static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignm return p; } -_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* -operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { +_LIBCPP_OVERRIDABLE_FUNCTION(_ZnwmSt11align_val_t, void*, operator new, (std::size_t size, std::align_val_t alignment)) +_THROW_BAD_ALLOC { void* p = operator_new_aligned_impl(size, alignment); if (p == nullptr) __throw_bad_alloc_shim(); @@ -148,7 +148,7 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s # if !_LIBCPP_HAS_EXCEPTIONS # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION _LIBCPP_ASSERT_SHIM( - !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)), + !std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)>(), "libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, " "but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " "`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will " @@ -168,16 +168,14 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s # endif } -_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* -operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { - return ::operator new(size, alignment); -} +_LIBCPP_OVERRIDABLE_FUNCTION(_ZnamSt11align_val_t, void*, operator new[], (size_t size, std::align_val_t alignment)) +_THROW_BAD_ALLOC { return ::operator new(size, alignment); } _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { # if !_LIBCPP_HAS_EXCEPTIONS # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION _LIBCPP_ASSERT_SHIM( - !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])), + !std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])>(), "libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, " "but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " "`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will " diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp index 37b1fc00cd7c..4937aafe8417 100644 --- a/libcxx/src/print.cpp +++ b/libcxx/src/print.cpp @@ -51,7 +51,7 @@ __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wst __view.size(), nullptr, nullptr) == 0) { - __throw_system_error(filesystem::detail::make_windows_error(GetLastError()), "failed to write formatted output"); + __throw_system_error(filesystem::detail::get_last_error(), "failed to write formatted output"); } } # endif // _LIBCPP_HAS_WIDE_CHARACTERS diff --git a/libcxx/src/system_error.cpp b/libcxx/src/system_error.cpp index d555bca995c4..d5ec73084f63 100644 --- a/libcxx/src/system_error.cpp +++ b/libcxx/src/system_error.cpp @@ -14,6 +14,7 @@ #include <cstdio> #include <cstdlib> #include <cstring> +#include <optional> #include <string.h> #include <string> #include <system_error> @@ -24,8 +25,123 @@ # include <android/api-level.h> #endif +#if defined(_LIBCPP_WIN32API) +# include <windows.h> +# include <winerror.h> +#endif + _LIBCPP_BEGIN_NAMESPACE_STD +#if defined(_LIBCPP_WIN32API) + +namespace { +std::optional<errc> __win_err_to_errc(int err) { + switch (err) { + case ERROR_ACCESS_DENIED: + return errc::permission_denied; + case ERROR_ALREADY_EXISTS: + return errc::file_exists; + case ERROR_BAD_NETPATH: + return errc::no_such_file_or_directory; + case ERROR_BAD_PATHNAME: + return errc::no_such_file_or_directory; + case ERROR_BAD_UNIT: + return errc::no_such_device; + case ERROR_BROKEN_PIPE: + return errc::broken_pipe; + case ERROR_BUFFER_OVERFLOW: + return errc::filename_too_long; + case ERROR_BUSY: + return errc::device_or_resource_busy; + case ERROR_BUSY_DRIVE: + return errc::device_or_resource_busy; + case ERROR_CANNOT_MAKE: + return errc::permission_denied; + case ERROR_CANTOPEN: + return errc::io_error; + case ERROR_CANTREAD: + return errc::io_error; + case ERROR_CANTWRITE: + return errc::io_error; + case ERROR_CURRENT_DIRECTORY: + return errc::permission_denied; + case ERROR_DEV_NOT_EXIST: + return errc::no_such_device; + case ERROR_DEVICE_IN_USE: + return errc::device_or_resource_busy; + case ERROR_DIR_NOT_EMPTY: + return errc::directory_not_empty; + case ERROR_DIRECTORY: + return errc::invalid_argument; + case ERROR_DISK_FULL: + return errc::no_space_on_device; + case ERROR_FILE_EXISTS: + return errc::file_exists; + case ERROR_FILE_NOT_FOUND: + return errc::no_such_file_or_directory; + case ERROR_HANDLE_DISK_FULL: + return errc::no_space_on_device; + case ERROR_INVALID_ACCESS: + return errc::permission_denied; + case ERROR_INVALID_DRIVE: + return errc::no_such_device; + case ERROR_INVALID_FUNCTION: + return errc::function_not_supported; + case ERROR_INVALID_HANDLE: + return errc::invalid_argument; + case ERROR_INVALID_NAME: + return errc::no_such_file_or_directory; + case ERROR_INVALID_PARAMETER: + return errc::invalid_argument; + case ERROR_LOCK_VIOLATION: + return errc::no_lock_available; + case ERROR_LOCKED: + return errc::no_lock_available; + case ERROR_NEGATIVE_SEEK: + return errc::invalid_argument; + case ERROR_NOACCESS: + return errc::permission_denied; + case ERROR_NOT_ENOUGH_MEMORY: + return errc::not_enough_memory; + case ERROR_NOT_READY: + return errc::resource_unavailable_try_again; + case ERROR_NOT_SAME_DEVICE: + return errc::cross_device_link; + case ERROR_NOT_SUPPORTED: + return errc::not_supported; + case ERROR_OPEN_FAILED: + return errc::io_error; + case ERROR_OPEN_FILES: + return errc::device_or_resource_busy; + case ERROR_OPERATION_ABORTED: + return errc::operation_canceled; + case ERROR_OUTOFMEMORY: + return errc::not_enough_memory; + case ERROR_PATH_NOT_FOUND: + return errc::no_such_file_or_directory; + case ERROR_READ_FAULT: + return errc::io_error; + case ERROR_REPARSE_TAG_INVALID: + return errc::invalid_argument; + case ERROR_RETRY: + return errc::resource_unavailable_try_again; + case ERROR_SEEK: + return errc::io_error; + case ERROR_SHARING_VIOLATION: + return errc::permission_denied; + case ERROR_TOO_MANY_OPEN_FILES: + return errc::too_many_files_open; + case ERROR_WRITE_FAULT: + return errc::io_error; + case ERROR_WRITE_PROTECT: + return errc::permission_denied; + default: + return {}; + } +} +} // namespace +#endif + namespace { #if _LIBCPP_HAS_THREADS @@ -157,19 +273,52 @@ public: const char* __system_error_category::name() const noexcept { return "system"; } string __system_error_category::message(int ev) const { -#ifdef _LIBCPP_ELAST +#ifdef _LIBCPP_WIN32API + std::string result; + char* str = nullptr; + unsigned long num_chars = ::FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + ev, + 0, + reinterpret_cast<char*>(&str), + 0, + nullptr); + auto is_whitespace = [](char ch) { return ch == '\n' || ch == '\r' || ch == ' '; }; + while (num_chars > 0 && is_whitespace(str[num_chars - 1])) + --num_chars; + + if (num_chars) + result = std::string(str, num_chars); + else + result = "Unknown error"; + + LocalFree(str); + return result; +#else +# ifdef _LIBCPP_ELAST if (ev > _LIBCPP_ELAST) return string("unspecified system_category error"); -#endif // _LIBCPP_ELAST +# endif // _LIBCPP_ELAST return __do_message::message(ev); +#endif } error_condition __system_error_category::default_error_condition(int ev) const noexcept { -#ifdef _LIBCPP_ELAST +#ifdef _LIBCPP_WIN32API + // Remap windows error codes to generic error codes if possible. + if (ev == 0) + return error_condition(0, generic_category()); + if (auto maybe_errc = __win_err_to_errc(ev)) + return error_condition(static_cast<int>(*maybe_errc), generic_category()); + return error_condition(ev, system_category()); +#else +# ifdef _LIBCPP_ELAST if (ev > _LIBCPP_ELAST) return error_condition(ev, system_category()); -#endif // _LIBCPP_ELAST +# endif // _LIBCPP_ELAST return error_condition(ev, generic_category()); +#endif } const error_category& system_category() noexcept { @@ -213,7 +362,7 @@ system_error::~system_error() noexcept {} void __throw_system_error(int ev, const char* what_arg) { #if _LIBCPP_HAS_EXCEPTIONS - std::__throw_system_error(error_code(ev, system_category()), what_arg); + std::__throw_system_error(error_code(ev, generic_category()), what_arg); #else // The above could also handle the no-exception case, but for size, avoid referencing system_category() unnecessarily. _LIBCPP_VERBOSE_ABORT( diff --git a/libcxx/test/benchmarks/numeric/gcd.bench.cpp b/libcxx/test/benchmarks/numeric/gcd.bench.cpp index abbc7e9dd04f..ca5fed59463a 100644 --- a/libcxx/test/benchmarks/numeric/gcd.bench.cpp +++ b/libcxx/test/benchmarks/numeric/gcd.bench.cpp @@ -25,7 +25,7 @@ static std::array<T, 1000> generate(std::uniform_int_distribution<T> distributio static void bm_gcd_random(benchmark::State& state) { std::array data = generate<int>(); - while (state.KeepRunningBatch(data.size())) + while (state.KeepRunningBatch(data.size() * data.size())) for (auto v0 : data) for (auto v1 : data) benchmark::DoNotOptimize(std::gcd(v0, v1)); diff --git a/libcxx/test/libcxx/clang_tidy.gen.py b/libcxx/test/libcxx/clang_tidy.gen.py index 0db9c0d14b19..06f277e901d3 100644 --- a/libcxx/test/libcxx/clang_tidy.gen.py +++ b/libcxx/test/libcxx/clang_tidy.gen.py @@ -33,8 +33,7 @@ for header in public_headers: {lit_header_undeprecations.get(header, '')} // TODO: run clang-tidy with modules enabled once they are supported -// RUN: %{{clang-tidy}} %s --warnings-as-errors=* -header-filter=.* --checks='-*,libcpp-*' --load=%{{test-tools-dir}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{compile_flags}} -fno-modules -// RUN: %{{clang-tidy}} %s --warnings-as-errors=* -header-filter=.* --config-file=%{{libcxx-dir}}/.clang-tidy -- -Wweak-vtables %{{compile_flags}} -fno-modules +// RUN: %{{clang-tidy}} %s --warnings-as-errors=* -header-filter=.* --config-file=%{{libcxx-dir}}/.clang-tidy --load=%{{test-tools-dir}}/clang_tidy_checks/libcxx-tidy.plugin -- -Wweak-vtables %{{compile_flags}} -fno-modules #include <{header}> """) diff --git a/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp b/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp new file mode 100644 index 000000000000..6d1748e64502 --- /dev/null +++ b/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <forward_list> + +// Test hardening assertions for std::forward_list. + +// REQUIRES: has-unix-headers +// REQUIRES: libcpp-hardening-mode={{extensive|debug}} +// UNSUPPORTED: c++03 +// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing + +#include <forward_list> + +#include "check_assertion.h" + +int main(int, char**) { + { // Default-constructed list. + std::forward_list<int> c; + const auto& const_c = c; + TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list"); + TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list"); + TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list"); + } + + { // Non-empty list becomes empty. + std::forward_list<int> c; + const auto& const_c = c; + c.push_front(1); + + // Check that there's no assertion on valid access. + (void)c.front(); + (void)const_c.front(); + + c.pop_front(); + TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list"); + TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list"); + TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list"); + } + + return 0; +} diff --git a/libcxx/test/libcxx/containers/sequences/vector.bool/assert.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector.bool/assert.pass.cpp new file mode 100644 index 000000000000..41badad8f569 --- /dev/null +++ b/libcxx/test/libcxx/containers/sequences/vector.bool/assert.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <vector> + +// Test hardening assertions for std::vector<bool>. + +// REQUIRES: has-unix-headers +// UNSUPPORTED: libcpp-hardening-mode=none +// UNSUPPORTED: c++03 +// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing + +#include <vector> + +#include "check_assertion.h" +#include "min_allocator.h" + +template <class Allocator> +void test() { + std::vector<bool, Allocator> c; + TEST_LIBCPP_ASSERT_FAILURE(c.front(), "vector<bool>::front() called on an empty vector"); + TEST_LIBCPP_ASSERT_FAILURE(c.back(), "vector<bool>::back() called on an empty vector"); + TEST_LIBCPP_ASSERT_FAILURE(c[0], "vector<bool>::operator[] index out of bounds"); + TEST_LIBCPP_ASSERT_FAILURE(c.pop_back(), "vector<bool>::pop_back called on an empty vector"); + + // Repeat the test with a const reference to test the const overloads. + { + const std::vector<bool, Allocator>& cc = c; + TEST_LIBCPP_ASSERT_FAILURE(cc.front(), "vector<bool>::front() called on an empty vector"); + TEST_LIBCPP_ASSERT_FAILURE(cc.back(), "vector<bool>::back() called on an empty vector"); + TEST_LIBCPP_ASSERT_FAILURE(cc[0], "vector<bool>::operator[] index out of bounds"); + } + + c.push_back(true); + c.push_back(false); + c.push_back(true); + TEST_LIBCPP_ASSERT_FAILURE(c[3], "vector<bool>::operator[] index out of bounds"); + TEST_LIBCPP_ASSERT_FAILURE(c[100], "vector<bool>::operator[] index out of bounds"); + + // Repeat the test with a const reference to test the const overloads. + { + const std::vector<bool, Allocator>& cc = c; + TEST_LIBCPP_ASSERT_FAILURE(cc[3], "vector<bool>::operator[] index out of bounds"); + TEST_LIBCPP_ASSERT_FAILURE(cc[100], "vector<bool>::operator[] index out of bounds"); + } + + TEST_LIBCPP_ASSERT_FAILURE( + c.erase(c.end()), "vector<bool>::erase(iterator) called with a non-dereferenceable iterator"); + TEST_LIBCPP_ASSERT_FAILURE( + c.erase(c.begin() + 1, c.begin()), "vector<bool>::erase(iterator, iterator) called with an invalid range"); +} + +int main(int, char**) { + test<std::allocator<bool>>(); + test<min_allocator<bool>>(); + + return 0; +} diff --git a/libcxx/test/libcxx/diagnostics/system_error_win_codes.pass.cpp b/libcxx/test/libcxx/diagnostics/system_error_win_codes.pass.cpp new file mode 100644 index 000000000000..799a5b5c0b08 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/system_error_win_codes.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: windows + +// Validate that system_error on windows accepts Windows' System Error Codes (as +// used by win32 APIs and reported by GetLastError), and that they are properly +// translated to generic conditions. + +#include <windows.h> +#include <system_error> +#include <cassert> + +#include "test_macros.h" + +int main(int, char**) { + LIBCPP_ASSERT(std::error_code(ERROR_ACCESS_DENIED, std::system_category()) == std::errc::permission_denied); + LIBCPP_ASSERT(std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()) == std::errc::no_such_file_or_directory); + return 0; +} diff --git a/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp b/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp index cd998d46b7e8..c2afa6b8dfd0 100644 --- a/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp +++ b/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp @@ -17,24 +17,47 @@ #include <type_traits> #include "atomic_helpers.h" +#include "test_helper.h" #include "test_macros.h" template <typename T> struct TestExchange { void operator()() const { - T x(T(1)); - std::atomic_ref<T> const a(x); + { + T x(T(1)); + std::atomic_ref<T> const a(x); + + { + std::same_as<T> decltype(auto) y = a.exchange(T(2)); + assert(y == T(1)); + ASSERT_NOEXCEPT(a.exchange(T(2))); + } + + { + std::same_as<T> decltype(auto) y = a.exchange(T(3), std::memory_order_seq_cst); + assert(y == T(2)); + ASSERT_NOEXCEPT(a.exchange(T(3), std::memory_order_seq_cst)); + } + } + // memory_order::release { - std::same_as<T> decltype(auto) y = a.exchange(T(2)); - assert(y == T(1)); - ASSERT_NOEXCEPT(a.exchange(T(2))); + auto exchange = [](std::atomic_ref<T> const& x, T, T new_val) { + x.exchange(new_val, std::memory_order::release); + }; + auto load = [](std::atomic_ref<T> const& x) { return x.load(std::memory_order::acquire); }; + test_acquire_release<T>(exchange, load); } + // memory_order::seq_cst { - std::same_as<T> decltype(auto) y = a.exchange(T(3), std::memory_order_seq_cst); - assert(y == T(2)); - ASSERT_NOEXCEPT(a.exchange(T(3), std::memory_order_seq_cst)); + auto exchange_no_arg = [](std::atomic_ref<T> const& x, T, T new_val) { x.exchange(new_val); }; + auto exchange_with_order = [](std::atomic_ref<T> const& x, T, T new_val) { + x.exchange(new_val, std::memory_order::seq_cst); + }; + auto load = [](std::atomic_ref<T> const& x) { return x.load(); }; + test_seq_cst<T>(exchange_no_arg, load); + test_seq_cst<T>(exchange_with_order, load); } } }; diff --git a/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp new file mode 100644 index 000000000000..16832dd831e6 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <vector> + +// reference at(size_type n); // constexpr since C++20 + +#include <cassert> +#include <memory> +#include <vector> + +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" + +#ifndef TEST_HAS_NO_EXCEPTIONS +# include <stdexcept> +#endif + +template <typename Allocator> +TEST_CONSTEXPR_CXX20 void test() { + using C = std::vector<bool, Allocator>; + using reference = typename C::reference; + bool a[] = {1, 0, 1, 0, 1}; + C v(a, a + sizeof(a) / sizeof(a[0])); + ASSERT_SAME_TYPE(reference, decltype(v.at(0))); + assert(v.at(0) == true); + assert(v.at(1) == false); + assert(v.at(2) == true); + assert(v.at(3) == false); + assert(v.at(4) == true); + v.at(1) = 1; + assert(v.at(1) == true); + v.at(3) = 1; + assert(v.at(3) == true); +} + +template <typename Allocator> +void test_exception() { +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool a[] = {1, 0, 1, 1}; + using C = std::vector<bool, Allocator>; + C v(a, a + sizeof(a) / sizeof(a[0])); + + try { + TEST_IGNORE_NODISCARD v.at(4); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(5); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(6); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + using size_type = typename C::size_type; + TEST_IGNORE_NODISCARD v.at(static_cast<size_type>(-1)); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } + + { + std::vector<bool, Allocator> v; + try { + TEST_IGNORE_NODISCARD v.at(0); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } +#endif +} + +TEST_CONSTEXPR_CXX20 bool tests() { + test<std::allocator<bool> >(); + test<min_allocator<bool> >(); + test<test_allocator<bool> >(); + return true; +} + +void test_exceptions() { + test_exception<std::allocator<bool> >(); + test_exception<min_allocator<bool> >(); + test_exception<test_allocator<bool> >(); +} + +int main(int, char**) { + tests(); + test_exceptions(); + +#if TEST_STD_VER >= 20 + static_assert(tests()); +#endif + + return 0; +} diff --git a/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp new file mode 100644 index 000000000000..5ed794d13f19 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <vector> + +// const_reference at(size_type n) const; // constexpr since C++20 + +#include <cassert> +#include <memory> +#include <vector> + +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" + +#ifndef TEST_HAS_NO_EXCEPTIONS +# include <stdexcept> +#endif + +template <typename Allocator> +TEST_CONSTEXPR_CXX20 void test() { + using C = const std::vector<bool, Allocator>; + using const_reference = typename C::const_reference; + bool a[] = {1, 0, 1, 0, 1}; + C v(a, a + sizeof(a) / sizeof(a[0])); + ASSERT_SAME_TYPE(const_reference, decltype(v.at(0))); + assert(v.at(0) == true); + assert(v.at(1) == false); + assert(v.at(2) == true); + assert(v.at(3) == false); + assert(v.at(4) == true); +} + +template <typename Allocator> +void test_exception() { +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool a[] = {1, 0, 1, 1}; + using C = const std::vector<bool, Allocator>; + C v(a, a + sizeof(a) / sizeof(a[0])); + + try { + TEST_IGNORE_NODISCARD v.at(4); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(5); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(6); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + using size_type = typename C::size_type; + TEST_IGNORE_NODISCARD v.at(static_cast<size_type>(-1)); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } + + { + std::vector<bool, Allocator> v; + try { + TEST_IGNORE_NODISCARD v.at(0); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } +#endif +} + +TEST_CONSTEXPR_CXX20 bool tests() { + test<std::allocator<bool> >(); + test<min_allocator<bool> >(); + test<test_allocator<bool> >(); + return true; +} + +void test_exceptions() { + test_exception<std::allocator<bool> >(); + test_exception<min_allocator<bool> >(); + test_exception<test_allocator<bool> >(); +} + +int main(int, char**) { + tests(); + test_exceptions(); + +#if TEST_STD_VER >= 20 + static_assert(tests()); +#endif + + return 0; +} diff --git a/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp index f1f49733280b..a8b565bb0ab9 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp @@ -22,6 +22,10 @@ #include "test_macros.h" +#ifndef _WIN32 +# define TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY +#endif + int main(int, char**) { std::error_code e_code1(5, std::generic_category()); std::error_code e_code2(5, std::system_category()); @@ -45,7 +49,9 @@ int main(int, char**) { assert(e_code2 == e_code2); assert(e_code2 != e_code3); assert(e_code2 != e_code4); +#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY LIBCPP_ASSERT(e_code2 == e_condition1); +#endif assert(e_code2 == e_condition2); LIBCPP_ASSERT(e_code2 != e_condition3); assert(e_code2 != e_condition4); @@ -65,11 +71,15 @@ int main(int, char**) { assert(e_code4 == e_code4); LIBCPP_ASSERT(e_code4 != e_condition1); assert(e_code4 != e_condition2); +#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY LIBCPP_ASSERT(e_code4 == e_condition3); +#endif assert(e_code4 == e_condition4); assert(e_condition1 == e_code1); +#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY LIBCPP_ASSERT(e_condition1 == e_code2); +#endif assert(e_condition1 != e_code3); LIBCPP_ASSERT(e_condition1 != e_code4); assert(e_condition1 == e_condition1); @@ -89,7 +99,9 @@ int main(int, char**) { assert(e_condition3 != e_code1); LIBCPP_ASSERT(e_condition3 != e_code2); assert(e_condition3 == e_code3); +#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY LIBCPP_ASSERT(e_condition3 == e_code4); +#endif assert(e_condition3 != e_condition1); assert(e_condition3 != e_condition2); assert(e_condition3 == e_condition3); diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp index 9f7eb42bc78d..f7f43132902f 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp @@ -29,8 +29,11 @@ int main(int, char**) { assert(!m1.empty()); assert(!m2.empty()); assert(!m3.empty()); +#ifndef _WIN32 + // On windows, system_category is distinct. LIBCPP_ASSERT(m1 == m2); - assert(m1 != m3); +#endif + assert(m2 != m3); return 0; } diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp index 6ba33ba44ca4..255cbe75e2fa 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp @@ -33,7 +33,12 @@ int main(int, char**) { { const std::error_category& e_cat1 = std::system_category(); std::error_condition e_cond = e_cat1.default_error_condition(5); +#ifdef _WIN32 + // Windows' system error 5 is ERROR_ACCESS_DENIED, which maps to generic code permission_denied. + LIBCPP_ASSERT(e_cond.value() == static_cast<int>(std::errc::permission_denied)); +#else LIBCPP_ASSERT(e_cond.value() == 5); +#endif LIBCPP_ASSERT(e_cond.category() == std::generic_category()); assert(e_cat1.equivalent(5, e_cond)); diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp index 303a95a0128b..071ee7f6c891 100644 --- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp @@ -172,8 +172,13 @@ static void test_with_ec_dne() { file_status st = status(p, status_ec); file_status sym_st = symlink_status(p, sym_status_ec); std::error_code ec = GetTestEC(2); - auto CheckEC = [&](std::error_code const& other_ec) { - bool res = ec == other_ec; + auto CheckEC = [&](std::error_code const& other_ec) { + // Note: we're comparing equality of the _canonicalized_ error_condition + // here (unlike in other tests where we expect exactly the same + // error_code). This is because directory_entry can construct its own + // generic_category error when a file doesn't exist, instead of passing + // through an underlying system_category error. + bool res = ec.default_error_condition() == other_ec.default_error_condition(); ec = GetTestEC(2); return res; }; diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp index dd72232ee530..dec04df7ca01 100644 --- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp @@ -44,7 +44,7 @@ static void test_basic() { file_status es = e.status(eec); assert(ps.type() == es.type()); assert(ps.permissions() == es.permissions()); - assert(pec == eec); + assert(pec.default_error_condition() == eec.default_error_condition()); } for (const auto& p : TestCases) { const directory_entry e(p); diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp index 24e806950952..77da936382aa 100644 --- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp @@ -44,7 +44,7 @@ static void test_signature() { file_status es = e.symlink_status(eec); assert(ps.type() == es.type()); assert(ps.permissions() == es.permissions()); - assert(pec == eec); + assert(pec.default_error_condition() == eec.default_error_condition()); } for (const auto& p : TestCases) { const directory_entry e(p); diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp new file mode 100644 index 000000000000..29bc8e41250d --- /dev/null +++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 +// REQUIRES: linux +// UNSUPPORTED: no-filesystem +// XFAIL: no-localization +// UNSUPPORTED: availability-filesystem-missing + +// <filesystem> + +// bool copy_file(const path& from, const path& to); +// bool copy_file(const path& from, const path& to, error_code& ec) noexcept; +// bool copy_file(const path& from, const path& to, copy_options options); +// bool copy_file(const path& from, const path& to, copy_options options, +// error_code& ec) noexcept; + +#include <cassert> +#include <filesystem> +#include <system_error> + +#include "test_macros.h" +#include "filesystem_test_helper.h" + +namespace fs = std::filesystem; + +// Linux has various virtual filesystems such as /proc and /sys +// where files may have no length (st_size == 0), but still contain data. +// This is because the to-be-read data is usually generated ad-hoc by the reading syscall +// These files can not be copied with kernel-side copies like copy_file_range or sendfile, +// and must instead be copied via a traditional userspace read + write loop. +int main(int, char** argv) { + const fs::path procfile{"/proc/self/comm"}; + assert(file_size(procfile) == 0); + + scoped_test_env env; + std::error_code ec = GetTestEC(); + + const fs::path dest = env.make_env_path("dest"); + + assert(copy_file(procfile, dest, ec)); + assert(!ec); + + // /proc/self/comm contains the filename of the executable, plus a null terminator + assert(file_size(dest) == fs::path(argv[0]).filename().string().size() + 1); + + return 0; +} diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h index a63d645d1a01..2ad9efb32c60 100644 --- a/libcxx/test/support/filesystem_test_helper.h +++ b/libcxx/test/support/filesystem_test_helper.h @@ -583,7 +583,11 @@ struct ExceptionChecker { assert(ErrorIsImp(Err.code(), {expected_err})); assert(Err.path1() == expected_path1); assert(Err.path2() == expected_path2); +#ifndef _WIN32 + // On Windows, the error strings are windows error code strings, and don't + // match textually with the strings generated for generic std::errc::*. LIBCPP_ONLY(check_libcxx_string(Err)); +#endif } void check_libcxx_string(fs::filesystem_error const& Err) { diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt index 05c44e49b448..0f8f0e8864d0 100644 --- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt +++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt @@ -92,6 +92,7 @@ set(SOURCES header_exportable_declarations.cpp hide_from_abi.cpp internal_ftm_use.cpp + nodebug_on_aliases.cpp proper_version_checks.cpp qualify_declval.cpp robust_against_adl.cpp diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp index 54beed5e30be..bc7c8ce7ec44 100644 --- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp +++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp @@ -13,6 +13,7 @@ #include "header_exportable_declarations.hpp" #include "hide_from_abi.hpp" #include "internal_ftm_use.hpp" +#include "nodebug_on_aliases.hpp" #include "proper_version_checks.hpp" #include "qualify_declval.hpp" #include "robust_against_adl.hpp" @@ -26,6 +27,7 @@ public: check_factories.registerCheck<libcpp::header_exportable_declarations>("libcpp-header-exportable-declarations"); check_factories.registerCheck<libcpp::hide_from_abi>("libcpp-hide-from-abi"); check_factories.registerCheck<libcpp::internal_ftm_use>("libcpp-internal-ftms"); + check_factories.registerCheck<libcpp::nodebug_on_aliases>("libcpp-nodebug-on-aliases"); check_factories.registerCheck<libcpp::proper_version_checks>("libcpp-cpp-version-check"); check_factories.registerCheck<libcpp::robust_against_adl_check>("libcpp-robust-against-adl"); check_factories.registerCheck<libcpp::uglify_attributes>("libcpp-uglify-attributes"); diff --git a/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.cpp b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.cpp new file mode 100644 index 000000000000..9b96269e5980 --- /dev/null +++ b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang-tidy/ClangTidyCheck.h" + +#include "nodebug_on_aliases.hpp" +#include "utilities.hpp" + +namespace libcpp { +namespace { +AST_MATCHER(clang::NamedDecl, isPretty) { return !is_ugly_name(Node.getName()); } +} // namespace + +nodebug_on_aliases::nodebug_on_aliases(llvm::StringRef name, clang::tidy::ClangTidyContext* context) + : clang::tidy::ClangTidyCheck(name, context) {} + +void nodebug_on_aliases::registerMatchers(clang::ast_matchers::MatchFinder* finder) { + using namespace clang::ast_matchers; + finder->addMatcher( + typeAliasDecl(unless(anyOf(isPretty(), hasAttr(clang::attr::NoDebug), hasAncestor(functionDecl())))) + .bind("nodebug_on_internal_aliases"), + this); +} + +void nodebug_on_aliases::check(const clang::ast_matchers::MatchFinder::MatchResult& result) { + if (const auto* alias = result.Nodes.getNodeAs<clang::TypeAliasDecl>("nodebug_on_internal_aliases")) { + diag(alias->getBeginLoc(), "Internal aliases should always be marked _LIBCPP_NODEBUG"); + } +} +} // namespace libcpp diff --git a/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.hpp b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.hpp new file mode 100644 index 000000000000..1097e8910649 --- /dev/null +++ b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.hpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang-tidy/ClangTidyCheck.h" + +namespace libcpp { +class nodebug_on_aliases : public clang::tidy::ClangTidyCheck { +public: + nodebug_on_aliases(llvm::StringRef, clang::tidy::ClangTidyContext*); + void registerMatchers(clang::ast_matchers::MatchFinder*) override; + void check(const clang::ast_matchers::MatchFinder::MatchResult&) override; +}; +} // namespace libcpp diff --git a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp index 7812b236f613..24bacde6304b 100644 --- a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp +++ b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp @@ -10,20 +10,11 @@ #include "clang-tidy/ClangTidyModuleRegistry.h" #include "uglify_attributes.hpp" +#include "utilities.hpp" -#include <algorithm> -#include <array> -#include <span> -#include <string_view> +#include <optional> namespace { -bool isUgly(std::string_view str) { - if (str.size() < 2) - return false; - if (str[0] == '_' && str[1] >= 'A' && str[1] <= 'Z') - return true; - return str.find("__") != std::string_view::npos; -} // Starting with Clang 17 ToT C++23 support is provided by CPlusPlus23 instead // of C++23 support is provided by CPlusPlus2b. To allow a smooth transition for @@ -77,17 +68,15 @@ AST_MATCHER(clang::Attr, isPretty) { if (Node.isKeywordAttribute() || !Node.getAttrName()) return false; if (Node.isCXX11Attribute() && !Node.hasScope()) { - if (isUgly(Node.getAttrName()->getName())) + if (is_ugly_name(Node.getAttrName()->getName())) return false; return !llvm::is_contained( get_standard_attributes(Finder->getASTContext().getLangOpts()), Node.getAttrName()->getName()); } if (Node.hasScope()) - if (!isUgly(Node.getScopeName()->getName())) + if (!is_ugly_name(Node.getScopeName()->getName())) return true; - return !isUgly(Node.getAttrName()->getName()); - - return false; + return !is_ugly_name(Node.getAttrName()->getName()); } std::optional<std::string> getUglyfiedCXX11Attr(const clang::Attr& attr) { diff --git a/libcxx/test/tools/clang_tidy_checks/utilities.hpp b/libcxx/test/tools/clang_tidy_checks/utilities.hpp new file mode 100644 index 000000000000..b780efef2385 --- /dev/null +++ b/libcxx/test/tools/clang_tidy_checks/utilities.hpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LIBCXX_TEST_TOOLS_CLANG_TIDY_CHECKS_UTILITIES_HPP +#define LIBCXX_TEST_TOOLS_CLANG_TIDY_CHECKS_UTILITIES_HPP + +#include <string_view> + +inline bool is_ugly_name(std::string_view str) { + if (str.size() < 2) + return false; + if (str[0] == '_' && str[1] >= 'A' && str[1] <= 'Z') + return true; + return str.find("__") != std::string_view::npos; +} + +#endif // LIBCXX_TEST_TOOLS_CLANG_TIDY_CHECKS_UTILITIES_HPP diff --git a/libcxx/utils/libcxx-benchmark-json b/libcxx/utils/libcxx-benchmark-json new file mode 100755 index 000000000000..7f743c32caf4 --- /dev/null +++ b/libcxx/utils/libcxx-benchmark-json @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +set -e + +PROGNAME="$(basename "${0}")" +MONOREPO_ROOT="$(realpath $(dirname "${PROGNAME}"))" +function usage() { +cat <<EOF +Usage: +${PROGNAME} [-h|--help] <build-directory> benchmarks... + +Print the path to the JSON files containing benchmark results for the given benchmarks. + +This requires those benchmarks to have already been run, i.e. this only resolves the path +to the benchmark .json file within the build directory. + +<build-directory> The path to the build directory. +benchmarks... Paths of the benchmarks to extract the results for. Those paths are relative to '<monorepo-root>'. + +Example +======= +$ cmake -S runtimes -B build/ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" +$ libcxx-lit build/ -sv libcxx/test/benchmarks/algorithms/for_each.bench.cpp +$ less \$(${PROGNAME} build/ libcxx/test/benchmarks/algorithms/for_each.bench.cpp) +EOF +} + +if [[ "${1}" == "-h" || "${1}" == "--help" ]]; then + usage + exit 0 +fi + +if [[ $# -lt 1 ]]; then + usage + exit 1 +fi + +build_dir="${1}" +shift + +for benchmark in ${@}; do + # Normalize the paths by turning all benchmarks paths into absolute ones and then making them + # relative to the root of the monorepo. + benchmark="$(realpath ${benchmark})" + relative=$(python -c "import os; import sys; print(os.path.relpath(sys.argv[1], sys.argv[2]))" "${benchmark}" "${MONOREPO_ROOT}") + + # Extract components of the benchmark path + directory="$(dirname ${relative})" + file="$(basename ${relative})" + + # Reconstruct the (slightly weird) path to the benchmark json file. This should be kept in sync + # whenever the test suite changes. + json="${build_dir}/${directory}/Output/${file}.dir/benchmark-result.json" + if [[ -f "${json}" ]]; then + echo "${json}" + fi +done diff --git a/libcxx/utils/libcxx-compare-benchmarks b/libcxx/utils/libcxx-compare-benchmarks new file mode 100755 index 000000000000..e04820fc57ed --- /dev/null +++ b/libcxx/utils/libcxx-compare-benchmarks @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -e + +PROGNAME="$(basename "${0}")" +MONOREPO_ROOT="$(realpath $(dirname "${PROGNAME}"))" +function usage() { +cat <<EOF +Usage: +${PROGNAME} [-h|--help] <baseline-build> <candidate-build> benchmarks... + +Compare the given benchmarks between the baseline and the candidate build directories. + +This requires those benchmarks to have already been generated in both build directories. + +<baseline-build> The path to the build directory considered the baseline. +<candidate-build> The path to the build directory considered the candidate. +benchmarks... Paths of the benchmarks to compare. Those paths are relative to '<monorepo-root>'. + +Example +======= +$ libcxx-lit build1/ -sv libcxx/test/benchmarks/algorithms/for_each.bench.cpp +$ libcxx-lit build2/ -sv libcxx/test/benchmarks/algorithms/for_each.bench.cpp +$ ${PROGNAME} build1/ build2/ libcxx/test/benchmarks/algorithms/for_each.bench.cpp +EOF +} + +if [[ "${1}" == "-h" || "${1}" == "--help" ]]; then + usage + exit 0 +fi + +if [[ $# -lt 1 ]]; then + usage + exit 1 +fi + +baseline="${1}" +candidate="${2}" +shift; shift + +GBENCH="${MONOREPO_ROOT}/third-party/benchmark" + +python3 -m venv /tmp/libcxx-compare-benchmarks-venv +source /tmp/libcxx-compare-benchmarks-venv/bin/activate +pip3 install -r ${GBENCH}/tools/requirements.txt + +for benchmark in ${@}; do + base="$(${MONOREPO_ROOT}/libcxx/utils/libcxx-benchmark-json ${baseline} ${benchmark})" + cand="$(${MONOREPO_ROOT}/libcxx/utils/libcxx-benchmark-json ${candidate} ${benchmark})" + + if [[ ! -e "${base}" ]]; then + echo "Benchmark ${benchmark} does not exist in the baseline" + continue + fi + if [[ ! -e "${cand}" ]]; then + echo "Benchmark ${benchmark} does not exist in the candidate" + continue + fi + + "${GBENCH}/tools/compare.py" benchmarks "${base}" "${cand}" +done |
