Skip to content

Commit a1161b8

Browse files
committed
Fix to_ulong to throw overflow_error as expected
1 parent d462d7b commit a1161b8

File tree

1 file changed

+45
-25
lines changed

1 file changed

+45
-25
lines changed

libcxx/include/bitset

+45-25
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;
@@ -509,6 +512,10 @@ protected:
509512
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
510513

511514
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
515+
516+
private:
517+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(false_type) const;
518+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type) const;
512519
};
513520

514521
template <size_t _Size>
@@ -543,6 +550,19 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
543550

544551
template <size_t _Size>
545552
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
553+
return __to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
554+
}
555+
556+
template <size_t _Size>
557+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(false_type) const {
558+
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
559+
__throw_overflow_error("__bitset<1, _Size>::__to_ulong overflow error");
560+
561+
return static_cast<unsigned long>(__first_);
562+
}
563+
564+
template <size_t _Size>
565+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(true_type) const {
546566
return static_cast<unsigned long>(__first_);
547567
}
548568

0 commit comments

Comments
 (0)