Skip to content

Commit 27a396d

Browse files
authored
Merge pull request #25572 from alexrp/libcxx-backports
`libcxx`: backport llvm/llvm-project#155476, llvm/llvm-project#147389, llvm/llvm-project#155786
2 parents 4edebf4 + bc58b5d commit 27a396d

File tree

6 files changed

+67
-15
lines changed

6 files changed

+67
-15
lines changed

lib/libcxx/include/__algorithm/sort.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,9 @@ __sort<__less<long double>&, long double*>(long double*, long double*, __less<lo
860860
template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
861861
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
862862
__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+
863866
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
864867
difference_type __depth_limit = 2 * std::__bit_log2(std::__to_unsigned_like(__last - __first));
865868

lib/libcxx/include/__bit/bit_log2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef _LIBCPP___BIT_BIT_LOG2_H
1010
#define _LIBCPP___BIT_BIT_LOG2_H
1111

12+
#include <__assert>
1213
#include <__bit/countl.h>
1314
#include <__config>
1415
#include <__type_traits/integer_traits.h>
@@ -23,6 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2324
template <class _Tp>
2425
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __bit_log2(_Tp __t) _NOEXCEPT {
2526
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");
2628
return numeric_limits<_Tp>::digits - 1 - std::__countl_zero(__t);
2729
}
2830

lib/libcxx/include/__functional/hash.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <__type_traits/is_enum.h>
2222
#include <__type_traits/is_floating_point.h>
2323
#include <__type_traits/is_integral.h>
24+
#include <__type_traits/is_unqualified.h>
2425
#include <__type_traits/underlying_type.h>
2526
#include <__utility/pair.h>
2627
#include <__utility/swap.h>
@@ -355,25 +356,30 @@ struct __hash_impl {
355356
};
356357

357358
template <class _Tp>
358-
struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function<_Tp, size_t> {
359+
struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value && __is_unqualified_v<_Tp> > >
360+
: __unary_function<_Tp, size_t> {
359361
_LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {
360362
using type = __underlying_type_t<_Tp>;
361363
return hash<type>()(static_cast<type>(__v));
362364
}
363365
};
364366

365367
template <class _Tp>
366-
struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) <= sizeof(size_t))> >
368+
struct __hash_impl<
369+
_Tp,
370+
__enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) <= sizeof(size_t))> >
367371
: __unary_function<_Tp, size_t> {
368372
_LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { return static_cast<size_t>(__v); }
369373
};
370374

371375
template <class _Tp>
372-
struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) > sizeof(size_t))> >
376+
struct __hash_impl<_Tp,
377+
__enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) > sizeof(size_t))> >
373378
: __scalar_hash<_Tp> {};
374379

375380
template <class _Tp>
376-
struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value> > : __scalar_hash<_Tp> {
381+
struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value && __is_unqualified_v<_Tp> > >
382+
: __scalar_hash<_Tp> {
377383
_LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {
378384
// -0.0 and 0.0 should return same hash
379385
if (__v == 0.0f)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
20+
template <class _Tp>
21+
inline 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

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,14 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
821821

822822
template <class _CharT, class _Traits>
823823
typename 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+
824832
if (__file_ == nullptr)
825833
return traits_type::eof();
826834
__write_mode();
@@ -841,8 +849,9 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
841849

842850
if (__always_noconv_) {
843851
size_t __n = static_cast<size_t>(this->pptr() - this->pbase());
844-
if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n)
845-
return traits_type::eof();
852+
if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) {
853+
return __failed();
854+
}
846855
} else {
847856
if (!__cv_)
848857
std::__throw_bad_cast();
@@ -854,34 +863,38 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
854863
char* __extbuf_end = __extbuf_;
855864
do {
856865
codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);
857-
if (__end == __b)
858-
return traits_type::eof();
866+
if (__end == __b) {
867+
return __failed();
868+
}
859869

860870
// No conversion needed: output characters directly to the file, done.
861871
if (__r == codecvt_base::noconv) {
862872
size_t __n = static_cast<size_t>(__p - __b);
863-
if (std::fwrite(__b, 1, __n, __file_) != __n)
864-
return traits_type::eof();
873+
if (std::fwrite(__b, 1, __n, __file_) != __n) {
874+
return __failed();
875+
}
865876
break;
866877

867878
// Conversion successful: output the converted characters to the file, done.
868879
} else if (__r == codecvt_base::ok) {
869880
size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
870-
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n)
871-
return traits_type::eof();
881+
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
882+
return __failed();
883+
}
872884
break;
873885

874886
// Conversion partially successful: output converted characters to the file and repeat with the
875887
// remaining characters.
876888
} else if (__r == codecvt_base::partial) {
877889
size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
878-
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n)
879-
return traits_type::eof();
890+
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
891+
return __failed();
892+
}
880893
__b = const_cast<char_type*>(__end);
881894
continue;
882895

883896
} else {
884-
return traits_type::eof();
897+
return __failed();
885898
}
886899
} while (true);
887900
}

lib/libcxx/src/algorithm.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
1313

1414
template <class Comp, class RandomAccessIterator>
1515
void __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+
1619
auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first));
1720

1821
// Only use bitset partitioning for arithmetic types. We should also check

0 commit comments

Comments
 (0)