[libcxx-commits] [libcxx] [libc++] Fix possible out of range access in bitset (PR #121348)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Mar 15 19:19:43 PDT 2025
https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/121348
>From 8af3d5f1c9ec368e01a19039aea7dfcf5dd504f1 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 30 Dec 2024 12:19:19 -0500
Subject: [PATCH 1/5] Improve bitset::to_ullong Implementation
---
libcxx/include/bitset | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index f905b6f274e3f..0c3afc4e6ad8f 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -136,6 +136,7 @@ template <size_t N> struct hash<std::bitset<N>>;
# include <__algorithm/fill.h>
# include <__algorithm/fill_n.h>
# include <__algorithm/find.h>
+# include <__algorithm/min.h>
# include <__assert>
# include <__bit_reference>
# include <__config>
@@ -382,8 +383,9 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
unsigned long long __r = __first_[0];
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
- for (size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i)
- __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT);
+ size_t __n_words = std::min<size_t>(_N_words, sizeof(unsigned long long) / sizeof(__storage_type));
+ for (size_t __i = 1; __i < __n_words; ++__i)
+ __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
_LIBCPP_DIAGNOSTIC_POP
return __r;
}
>From 654b1e5fa79fea3ea5344cca2b799b1a6e261be6 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Tue, 31 Dec 2024 01:44:59 -0500
Subject: [PATCH 2/5] Make variable constant expression
---
libcxx/include/bitset | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 0c3afc4e6ad8f..e5c03f4691520 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -383,7 +383,8 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
unsigned long long __r = __first_[0];
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
- size_t __n_words = std::min<size_t>(_N_words, sizeof(unsigned long long) / sizeof(__storage_type));
+ const size_t __ull_words = sizeof(unsigned long long) / sizeof(__storage_type);
+ const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
for (size_t __i = 1; __i < __n_words; ++__i)
__r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
_LIBCPP_DIAGNOSTIC_POP
>From 54df6ee92dc8cfe398b681177cc4b06e88801af7 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Wed, 1 Jan 2025 18:06:08 -0500
Subject: [PATCH 3/5] Apply @frederick-vs-ja suggestions to support 16-bit
platforms
---
libcxx/include/bitset | 74 +++++++++++++++++++++++++++++++------------
1 file changed, 54 insertions(+), 20 deletions(-)
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index e5c03f4691520..318d223ea8193 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -236,6 +236,8 @@ private:
# endif // _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
@@ -284,14 +286,23 @@ inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned lon
template <size_t _N_words, size_t _Size>
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
# ifndef _LIBCPP_CXX03_LANG
-# if __SIZEOF_SIZE_T__ == 8
- : __first_{__v}
-# elif __SIZEOF_SIZE_T__ == 4
+# if (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 1
+ : __first_{static_cast<__storage_type>(__v)}
+# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 2
+ : __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
+# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 4
+# if _N_words == 2
+ : __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
+# elif _N_words == 3
: __first_{static_cast<__storage_type>(__v),
- _Size >= 2 * __bits_per_word
- ? static_cast<__storage_type>(__v >> __bits_per_word)
- : static_cast<__storage_type>((__v >> __bits_per_word) &
- (__storage_type(1) << (_Size - __bits_per_word)) - 1)}
+ static_cast<__storage_type>(__v >> __bits_per_word),
+ static_cast<__storage_type>(__v >> (__bits_per_word * 2))}
+# else
+ : __first_{static_cast<__storage_type>(__v),
+ static_cast<__storage_type>(__v >> __bits_per_word),
+ static_cast<__storage_type>(__v >> (__bits_per_word * 2)),
+ static_cast<__storage_type>(__v >> (__bits_per_word * 3))}
+# endif
# else
# error This constructor has not been ported to this platform
# endif
@@ -345,15 +356,34 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const {
if (__i != __e)
std::__throw_overflow_error("bitset to_ulong overflow error");
- return __first_[0];
+ return to_ulong(true_type());
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
__bitset<_N_words, _Size>::to_ulong(true_type) const {
- return __first_[0];
+ return to_ulong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long)>());
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
+__bitset<_N_words, _Size>::to_ulong(true_type, false_type) const {
+ return static_cast<unsigned long>(__first_[0]);
}
+template <size_t _N_words, size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
+__bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
+ unsigned long __r = static_cast<unsigned long>(__first_[0]);
+ _LIBCPP_DIAGNOSTIC_PUSH
+ _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
+ const size_t __ul_words = sizeof(unsigned long) / sizeof(__storage_type);
+ const size_t __n_words = _N_words < __ul_words ? _N_words : __ul_words;
+ for (size_t __i = 1; __i < __n_words; ++__i)
+ __r |= static_cast<unsigned long>(__first_[__i]) << (__bits_per_word * __i);
+ _LIBCPP_DIAGNOSTIC_POP
+ return __r;
+}
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
__bitset<_N_words, _Size>::to_ullong(false_type) const {
@@ -374,19 +404,19 @@ __bitset<_N_words, _Size>::to_ullong(true_type) const {
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
- return __first_[0];
+ return static_cast<unsigned long long>(__first_[0]);
}
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
- unsigned long long __r = __first_[0];
+ unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
const size_t __ull_words = sizeof(unsigned long long) / sizeof(__storage_type);
- const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
+ const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
for (size_t __i = 1; __i < __n_words; ++__i)
- __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
+ __r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
_LIBCPP_DIAGNOSTIC_POP
return __r;
}
@@ -493,8 +523,11 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
template <size_t _Size>
inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
- : __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v)
- : static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - 1)) {}
+ : __first_(static_cast<__storage_type>(__v)) {
+ // Force __bits_per_word to be instantiated to avoid "gdb.error: There is no member or method named
+ // __bits_per_word"
+ (void)__bits_per_word;
+}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
@@ -521,12 +554,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
template <size_t _Size>
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
- return __first_;
+ return static_cast<unsigned long>(__first_);
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<1, _Size>::to_ullong() const {
- return __first_;
+ return static_cast<unsigned long long>(__first_);
}
template <size_t _Size>
@@ -590,8 +623,8 @@ protected:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0UL; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0ULL; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return true; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return false; }
@@ -621,7 +654,8 @@ public:
// 23.3.5.1 constructors:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : __base(__v) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT
+ : __base(sizeof(unsigned long long) * CHAR_BIT <= _Size ? __v : __v & ((1ULL << _Size) - 1)) {}
template <class _CharT, __enable_if_t<_IsCharLikeType<_CharT>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
const _CharT* __str,
>From d462d7b7ecc7de169b78c6acd6c9598e8752b1ba Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Fri, 3 Jan 2025 11:58:42 -0500
Subject: [PATCH 4/5] Fix gdb.error
---
libcxx/include/bitset | 33 +++++++++++----------------------
1 file changed, 11 insertions(+), 22 deletions(-)
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 318d223ea8193..a8b012f4bcbb7 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -144,6 +144,7 @@ template <size_t N> struct hash<std::bitset<N>>;
# include <__cstddef/size_t.h>
# include <__functional/hash.h>
# include <__functional/unary_function.h>
+# include <__type_traits/integral_constant.h>
# include <__type_traits/is_char_like_type.h>
# include <climits>
# include <stdexcept>
@@ -219,10 +220,10 @@ protected:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
- return to_ulong(integral_constant < bool, _Size< sizeof(unsigned long) * CHAR_BIT>());
+ return to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
- return to_ullong(integral_constant < bool, _Size< sizeof(unsigned long long) * CHAR_BIT>());
+ return to_ullong(_BoolConstant < _Size< sizeof(unsigned long long) * CHAR_BIT>());
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
@@ -309,7 +310,7 @@ inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long
# endif
{
# ifdef _LIBCPP_CXX03_LANG
- __init(__v, integral_constant<bool, sizeof(unsigned long long) == sizeof(__storage_type)>());
+ __init(__v, _BoolConstant<sizeof(unsigned long long) == sizeof(__storage_type)>());
# endif
}
@@ -351,9 +352,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Siz
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
__bitset<_N_words, _Size>::to_ulong(false_type) const {
- __const_iterator __e = __make_iter(_Size);
- __const_iterator __i = std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true);
- if (__i != __e)
+ if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
std::__throw_overflow_error("bitset to_ulong overflow error");
return to_ulong(true_type());
@@ -362,7 +361,7 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const {
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
__bitset<_N_words, _Size>::to_ulong(true_type) const {
- return to_ulong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long)>());
+ return to_ulong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long)>());
}
template <size_t _N_words, size_t _Size>
@@ -377,9 +376,7 @@ __bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
unsigned long __r = static_cast<unsigned long>(__first_[0]);
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
- const size_t __ul_words = sizeof(unsigned long) / sizeof(__storage_type);
- const size_t __n_words = _N_words < __ul_words ? _N_words : __ul_words;
- for (size_t __i = 1; __i < __n_words; ++__i)
+ for (size_t __i = 1; __i < _N_words; ++__i)
__r |= static_cast<unsigned long>(__first_[__i]) << (__bits_per_word * __i);
_LIBCPP_DIAGNOSTIC_POP
return __r;
@@ -387,9 +384,7 @@ __bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
__bitset<_N_words, _Size>::to_ullong(false_type) const {
- __const_iterator __e = __make_iter(_Size);
- __const_iterator __i = std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true);
- if (__i != __e)
+ if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) != __e)
std::__throw_overflow_error("bitset to_ullong overflow error");
return to_ullong(true_type());
@@ -398,7 +393,7 @@ __bitset<_N_words, _Size>::to_ullong(false_type) const {
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
__bitset<_N_words, _Size>::to_ullong(true_type) const {
- return to_ullong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long long)>());
+ return to_ullong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long long)>());
}
template <size_t _N_words, size_t _Size>
@@ -413,9 +408,7 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
- const size_t __ull_words = sizeof(unsigned long long) / sizeof(__storage_type);
- const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
- for (size_t __i = 1; __i < __n_words; ++__i)
+ for (size_t __i = 1; __i < _N_words; ++__i)
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
_LIBCPP_DIAGNOSTIC_POP
return __r;
@@ -523,11 +516,7 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
template <size_t _Size>
inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
- : __first_(static_cast<__storage_type>(__v)) {
- // Force __bits_per_word to be instantiated to avoid "gdb.error: There is no member or method named
- // __bits_per_word"
- (void)__bits_per_word;
-}
+ : __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v) : static_cast<__storage_type>(__v)) {}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
>From a1161b884bffa6341c24ac41cdbf53c0f3acbce5 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 24 Feb 2025 13:22:31 -0500
Subject: [PATCH 5/5] Fix to_ulong to throw overflow_error as expected
---
libcxx/include/bitset | 70 +++++++++++++++++++++++++++----------------
1 file changed, 45 insertions(+), 25 deletions(-)
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index a8b012f4bcbb7..a7de7ebccb1f6 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -220,10 +220,10 @@ protected:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
- return to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
+ return __to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
- return to_ullong(_BoolConstant < _Size< sizeof(unsigned long long) * CHAR_BIT>());
+ return __to_ullong(_BoolConstant < _Size< sizeof(unsigned long long) * CHAR_BIT>());
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
@@ -235,14 +235,14 @@ private:
void __init(unsigned long long __v, false_type) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
# endif // _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, true_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(false_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type, false_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type, true_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(false_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type, false_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type, true_type) const;
};
template <size_t _N_words, size_t _Size>
@@ -351,28 +351,28 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Siz
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
-__bitset<_N_words, _Size>::to_ulong(false_type) const {
+__bitset<_N_words, _Size>::__to_ulong(false_type) const {
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
- std::__throw_overflow_error("bitset to_ulong overflow error");
+ std::__throw_overflow_error("bitset __to_ulong overflow error");
- return to_ulong(true_type());
+ return __to_ulong(true_type());
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
-__bitset<_N_words, _Size>::to_ulong(true_type) const {
- return to_ulong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long)>());
+__bitset<_N_words, _Size>::__to_ulong(true_type) const {
+ return __to_ulong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long)>());
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
-__bitset<_N_words, _Size>::to_ulong(true_type, false_type) const {
+__bitset<_N_words, _Size>::__to_ulong(true_type, false_type) const {
return static_cast<unsigned long>(__first_[0]);
}
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
-__bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
+__bitset<_N_words, _Size>::__to_ulong(true_type, true_type) const {
unsigned long __r = static_cast<unsigned long>(__first_[0]);
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
@@ -381,34 +381,37 @@ __bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
_LIBCPP_DIAGNOSTIC_POP
return __r;
}
+
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
-__bitset<_N_words, _Size>::to_ullong(false_type) const {
+__bitset<_N_words, _Size>::__to_ullong(false_type) const {
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) != __e)
- std::__throw_overflow_error("bitset to_ullong overflow error");
+ std::__throw_overflow_error("bitset __to_ullong overflow error");
- return to_ullong(true_type());
+ return __to_ullong(true_type());
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
-__bitset<_N_words, _Size>::to_ullong(true_type) const {
- return to_ullong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long long)>());
+__bitset<_N_words, _Size>::__to_ullong(true_type) const {
+ return __to_ullong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long long)>());
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
-__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
+__bitset<_N_words, _Size>::__to_ullong(true_type, false_type) const {
return static_cast<unsigned long long>(__first_[0]);
}
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
-__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
+__bitset<_N_words, _Size>::__to_ullong(true_type, true_type) const {
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
- for (size_t __i = 1; __i < _N_words; ++__i)
+ const size_t __ull_wrods = (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1;
+ const size_t __n_words = _N_words < __ull_wrods ? _N_words : __ull_wrods;
+ for (size_t __i = 1; __i < __n_words; ++__i)
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
_LIBCPP_DIAGNOSTIC_POP
return __r;
@@ -509,6 +512,10 @@ protected:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
+
+private:
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(false_type) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type) const;
};
template <size_t _Size>
@@ -543,6 +550,19 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
template <size_t _Size>
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
+ return __to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
+}
+
+template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(false_type) const {
+ if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
+ __throw_overflow_error("__bitset<1, _Size>::__to_ulong overflow error");
+
+ return static_cast<unsigned long>(__first_);
+}
+
+template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(true_type) const {
return static_cast<unsigned long>(__first_);
}
More information about the libcxx-commits
mailing list