authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-15 00:24:35+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-10-15 00:24:35+02:00
log27a396db4fd2e9734dab63d203fb354084e2c237
tree998fe71c701da161fc7726694644532fa4d577dc
parent4edebf40d53c7e69afd088c9967f13ab8aafe1fd
parentbc58b5dc53cce066d224925ce8fb4bb79665a1d1
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #25572 from alexrp/libcxx-backports

`libcxx`: backport llvm/llvm-project#155476, llvm/llvm-project#147389, llvm/llvm-project#155786

6 files changed, 67 insertions(+), 15 deletions(-)

lib/libcxx/include/__algorithm/sort.h+3
...@@ -860,6 +860,9 @@ __sort<__less<long double>&, long double*>(long double*, long double*, __less<lo...@@ -860,6 +860,9 @@ __sort<__less<long double>&, long double*>(long double*, long double*, __less<lo
860template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>860template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
861_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void861_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
862__sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {862__sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
863 if (__first == __last) // log(0) is undefined, so don't try computing the depth
864 return;
865
863 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;866 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
864 difference_type __depth_limit = 2 * std::__bit_log2(std::__to_unsigned_like(__last - __first));867 difference_type __depth_limit = 2 * std::__bit_log2(std::__to_unsigned_like(__last - __first));
865868
lib/libcxx/include/__bit/bit_log2.h+2
...@@ -9,6 +9,7 @@...@@ -9,6 +9,7 @@
9#ifndef _LIBCPP___BIT_BIT_LOG2_H9#ifndef _LIBCPP___BIT_BIT_LOG2_H
10#define _LIBCPP___BIT_BIT_LOG2_H10#define _LIBCPP___BIT_BIT_LOG2_H
1111
12#include <__assert>
12#include <__bit/countl.h>13#include <__bit/countl.h>
13#include <__config>14#include <__config>
14#include <__type_traits/integer_traits.h>15#include <__type_traits/integer_traits.h>
...@@ -23,6 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD...@@ -23,6 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
23template <class _Tp>24template <class _Tp>
24_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __bit_log2(_Tp __t) _NOEXCEPT {25_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __bit_log2(_Tp __t) _NOEXCEPT {
25 static_assert(__is_unsigned_integer_v<_Tp>, "__bit_log2 requires an unsigned integer type");26 static_assert(__is_unsigned_integer_v<_Tp>, "__bit_log2 requires an unsigned integer type");
27 _LIBCPP_ASSERT_INTERNAL(__t != 0, "logarithm of 0 is undefined");
26 return numeric_limits<_Tp>::digits - 1 - std::__countl_zero(__t);28 return numeric_limits<_Tp>::digits - 1 - std::__countl_zero(__t);
27}29}
2830
lib/libcxx/include/__functional/hash.h+10-4
...@@ -21,6 +21,7 @@...@@ -21,6 +21,7 @@
21#include <__type_traits/is_enum.h>21#include <__type_traits/is_enum.h>
22#include <__type_traits/is_floating_point.h>22#include <__type_traits/is_floating_point.h>
23#include <__type_traits/is_integral.h>23#include <__type_traits/is_integral.h>
24#include <__type_traits/is_unqualified.h>
24#include <__type_traits/underlying_type.h>25#include <__type_traits/underlying_type.h>
25#include <__utility/pair.h>26#include <__utility/pair.h>
26#include <__utility/swap.h>27#include <__utility/swap.h>
...@@ -355,7 +356,8 @@ struct __hash_impl {...@@ -355,7 +356,8 @@ struct __hash_impl {
355};356};
356357
357template <class _Tp>358template <class _Tp>
358struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function<_Tp, size_t> {359struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value && __is_unqualified_v<_Tp> > >
360 : __unary_function<_Tp, size_t> {
359 _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {361 _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {
360 using type = __underlying_type_t<_Tp>;362 using type = __underlying_type_t<_Tp>;
361 return hash<type>()(static_cast<type>(__v));363 return hash<type>()(static_cast<type>(__v));
...@@ -363,17 +365,21 @@ struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function<...@@ -363,17 +365,21 @@ struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function<
363};365};
364366
365template <class _Tp>367template <class _Tp>
366struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) <= sizeof(size_t))> >368struct __hash_impl<
369 _Tp,
370 __enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) <= sizeof(size_t))> >
367 : __unary_function<_Tp, size_t> {371 : __unary_function<_Tp, size_t> {
368 _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { return static_cast<size_t>(__v); }372 _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { return static_cast<size_t>(__v); }
369};373};
370374
371template <class _Tp>375template <class _Tp>
372struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) > sizeof(size_t))> >376struct __hash_impl<_Tp,
377 __enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) > sizeof(size_t))> >
373 : __scalar_hash<_Tp> {};378 : __scalar_hash<_Tp> {};
374379
375template <class _Tp>380template <class _Tp>
376struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value> > : __scalar_hash<_Tp> {381struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value && __is_unqualified_v<_Tp> > >
382 : __scalar_hash<_Tp> {
377 _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {383 _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {
378 // -0.0 and 0.0 should return same hash384 // -0.0 and 0.0 should return same hash
379 if (__v == 0.0f)385 if (__v == 0.0f)
lib/libcxx/include/__type_traits/is_unqualified.h created+25
...@@ -0,0 +1,25 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H
10#define _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H
11
12#include <__config>
13
14#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15# pragma GCC system_header
16#endif
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20template <class _Tp>
21inline const bool __is_unqualified_v = __is_same(_Tp, __remove_cvref(_Tp));
22
23_LIBCPP_END_NAMESPACE_STD
24
25#endif // _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H
lib/libcxx/include/fstream+24-11
...@@ -821,6 +821,14 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>...@@ -821,6 +821,14 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
821821
822template <class _CharT, class _Traits>822template <class _CharT, class _Traits>
823typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {823typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
824 auto __failed = [this]() {
825 if (this->pptr() == this->epptr() + 1) {
826 this->pbump(-1); // lose the character we overflowed above -- we don't really have a
827 // choice since we couldn't commit the contents of the put area
828 }
829 return traits_type::eof();
830 };
831
824 if (__file_ == nullptr)832 if (__file_ == nullptr)
825 return traits_type::eof();833 return traits_type::eof();
826 __write_mode();834 __write_mode();
...@@ -841,8 +849,9 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>...@@ -841,8 +849,9 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
841849
842 if (__always_noconv_) {850 if (__always_noconv_) {
843 size_t __n = static_cast<size_t>(this->pptr() - this->pbase());851 size_t __n = static_cast<size_t>(this->pptr() - this->pbase());
844 if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n)852 if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) {
845 return traits_type::eof();853 return __failed();
854 }
846 } else {855 } else {
847 if (!__cv_)856 if (!__cv_)
848 std::__throw_bad_cast();857 std::__throw_bad_cast();
...@@ -854,34 +863,38 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>...@@ -854,34 +863,38 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
854 char* __extbuf_end = __extbuf_;863 char* __extbuf_end = __extbuf_;
855 do {864 do {
856 codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);865 codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);
857 if (__end == __b)866 if (__end == __b) {
858 return traits_type::eof();867 return __failed();
868 }
859869
860 // No conversion needed: output characters directly to the file, done.870 // No conversion needed: output characters directly to the file, done.
861 if (__r == codecvt_base::noconv) {871 if (__r == codecvt_base::noconv) {
862 size_t __n = static_cast<size_t>(__p - __b);872 size_t __n = static_cast<size_t>(__p - __b);
863 if (std::fwrite(__b, 1, __n, __file_) != __n)873 if (std::fwrite(__b, 1, __n, __file_) != __n) {
864 return traits_type::eof();874 return __failed();
875 }
865 break;876 break;
866877
867 // Conversion successful: output the converted characters to the file, done.878 // Conversion successful: output the converted characters to the file, done.
868 } else if (__r == codecvt_base::ok) {879 } else if (__r == codecvt_base::ok) {
869 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);880 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
870 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n)881 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
871 return traits_type::eof();882 return __failed();
883 }
872 break;884 break;
873885
874 // Conversion partially successful: output converted characters to the file and repeat with the886 // Conversion partially successful: output converted characters to the file and repeat with the
875 // remaining characters.887 // remaining characters.
876 } else if (__r == codecvt_base::partial) {888 } else if (__r == codecvt_base::partial) {
877 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);889 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
878 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n)890 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
879 return traits_type::eof();891 return __failed();
892 }
880 __b = const_cast<char_type*>(__end);893 __b = const_cast<char_type*>(__end);
881 continue;894 continue;
882895
883 } else {896 } else {
884 return traits_type::eof();897 return __failed();
885 }898 }
886 } while (true);899 } while (true);
887 }900 }
lib/libcxx/src/algorithm.cpp+3
...@@ -13,6 +13,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD...@@ -13,6 +13,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
1313
14template <class Comp, class RandomAccessIterator>14template <class Comp, class RandomAccessIterator>
15void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) {15void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) {
16 if (first == last) // log(0) is undefined, so don't try computing the depth
17 return;
18
16 auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first));19 auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first));
1720
18 // Only use bitset partitioning for arithmetic types. We should also check21 // Only use bitset partitioning for arithmetic types. We should also check