Skip to content

Commit 588b947

Browse files
committed
Fix to_ulong to throw overflow_error as expected
1 parent d18d6eb commit 588b947

File tree

1 file changed

+45
-25
lines changed

1 file changed

+45
-25
lines changed

libcxx/include/bitset

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,10 @@ protected:
220220

221221
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT;
222222
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
223-
return to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
223+
return __to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
224224
}
225225
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
226-
return to_ullong(_BoolConstant < _Size< sizeof(unsigned long long) * CHAR_BIT>());
226+
return __to_ullong(_BoolConstant < _Size< sizeof(unsigned long long) * CHAR_BIT>());
227227
}
228228

229229
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
@@ -235,14 +235,14 @@ private:
235235
void __init(unsigned long long __v, false_type) _NOEXCEPT;
236236
_LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
237237
# endif // _LIBCPP_CXX03_LANG
238-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
239-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
240-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
241-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
242-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
243-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
244-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
245-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, true_type) const;
238+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(false_type) const;
239+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type) const;
240+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type, false_type) const;
241+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type, true_type) const;
242+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(false_type) const;
243+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type) const;
244+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type, false_type) const;
245+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type, true_type) const;
246246
};
247247

248248
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
351351

352352
template <size_t _N_words, size_t _Size>
353353
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
354-
__bitset<_N_words, _Size>::to_ulong(false_type) const {
354+
__bitset<_N_words, _Size>::__to_ulong(false_type) const {
355355
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
356-
std::__throw_overflow_error("bitset to_ulong overflow error");
356+
std::__throw_overflow_error("bitset __to_ulong overflow error");
357357

358-
return to_ulong(true_type());
358+
return __to_ulong(true_type());
359359
}
360360

361361
template <size_t _N_words, size_t _Size>
362362
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
363-
__bitset<_N_words, _Size>::to_ulong(true_type) const {
364-
return to_ulong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long)>());
363+
__bitset<_N_words, _Size>::__to_ulong(true_type) const {
364+
return __to_ulong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long)>());
365365
}
366366

367367
template <size_t _N_words, size_t _Size>
368368
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
369-
__bitset<_N_words, _Size>::to_ulong(true_type, false_type) const {
369+
__bitset<_N_words, _Size>::__to_ulong(true_type, false_type) const {
370370
return static_cast<unsigned long>(__first_[0]);
371371
}
372372

373373
template <size_t _N_words, size_t _Size>
374374
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
375-
__bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
375+
__bitset<_N_words, _Size>::__to_ulong(true_type, true_type) const {
376376
unsigned long __r = static_cast<unsigned long>(__first_[0]);
377377
_LIBCPP_DIAGNOSTIC_PUSH
378378
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
@@ -381,34 +381,37 @@ __bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
381381
_LIBCPP_DIAGNOSTIC_POP
382382
return __r;
383383
}
384+
384385
template <size_t _N_words, size_t _Size>
385386
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
386-
__bitset<_N_words, _Size>::to_ullong(false_type) const {
387+
__bitset<_N_words, _Size>::__to_ullong(false_type) const {
387388
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) != __e)
388-
std::__throw_overflow_error("bitset to_ullong overflow error");
389+
std::__throw_overflow_error("bitset __to_ullong overflow error");
389390

390-
return to_ullong(true_type());
391+
return __to_ullong(true_type());
391392
}
392393

393394
template <size_t _N_words, size_t _Size>
394395
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
395-
__bitset<_N_words, _Size>::to_ullong(true_type) const {
396-
return to_ullong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long long)>());
396+
__bitset<_N_words, _Size>::__to_ullong(true_type) const {
397+
return __to_ullong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long long)>());
397398
}
398399

399400
template <size_t _N_words, size_t _Size>
400401
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
401-
__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
402+
__bitset<_N_words, _Size>::__to_ullong(true_type, false_type) const {
402403
return static_cast<unsigned long long>(__first_[0]);
403404
}
404405

405406
template <size_t _N_words, size_t _Size>
406407
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
407-
__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
408+
__bitset<_N_words, _Size>::__to_ullong(true_type, true_type) const {
408409
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
409410
_LIBCPP_DIAGNOSTIC_PUSH
410411
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
411-
for (size_t __i = 1; __i < _N_words; ++__i)
412+
const size_t __ull_wrods = (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1;
413+
const size_t __n_words = _N_words < __ull_wrods ? _N_words : __ull_wrods;
414+
for (size_t __i = 1; __i < __n_words; ++__i)
412415
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
413416
_LIBCPP_DIAGNOSTIC_POP
414417
return __r;
@@ -513,6 +516,10 @@ protected:
513516
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
514517

515518
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
519+
520+
private:
521+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(false_type) const;
522+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type) const;
516523
};
517524

518525
template <size_t _Size>
@@ -547,6 +554,19 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
547554

548555
template <size_t _Size>
549556
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
557+
return __to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
558+
}
559+
560+
template <size_t _Size>
561+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(false_type) const {
562+
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
563+
__throw_overflow_error("__bitset<1, _Size>::__to_ulong overflow error");
564+
565+
return static_cast<unsigned long>(__first_);
566+
}
567+
568+
template <size_t _Size>
569+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(true_type) const {
550570
return static_cast<unsigned long>(__first_);
551571
}
552572

0 commit comments

Comments
 (0)