Skip to content

Commit 48db51b

Browse files
<random>: Prevent full-width shifts in independent_bits_engine (#5740)
Co-authored-by: Stephan T. Lavavej <[email protected]>
1 parent 358868a commit 48db51b

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

stl/inc/random

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,29 +1891,27 @@ public:
18911891
}
18921892

18931893
_NODISCARD result_type operator()() {
1894-
size_t _Idx = 0;
1895-
result_type _Res = 0;
18961894
result_type _Mask = ((result_type{1} << (_Wx0 - 1)) << 1) - 1;
18971895
_Eres _Val;
18981896

1897+
do { // get a small enough value
1898+
_Val = _Eng() - (_Engine::min) ();
1899+
} while (_Val > _Yx0);
1900+
result_type _Res = static_cast<result_type>(_Val) & _Mask;
1901+
1902+
size_t _Idx = 1;
18991903
for (; _Idx < _Nx0; ++_Idx) { // pack _Wx0-bit values
1900-
for (;;) { // get a small enough value
1904+
do {
19011905
_Val = _Eng() - (_Engine::min) ();
1902-
if (_Val <= _Yx0) {
1903-
break;
1904-
}
1905-
}
1906+
} while (_Val > _Yx0);
19061907
_Res = _Res << _Wx0 | (static_cast<result_type>(_Val) & _Mask);
19071908
}
19081909

19091910
_Mask = _Mask << 1 | 1;
19101911
for (; _Idx < _Nx; ++_Idx) { // pack _Wx0+1-bit values
1911-
for (;;) { // get a small enough value
1912+
do {
19121913
_Val = _Eng() - (_Engine::min) ();
1913-
if (_Val <= _Yx1) {
1914-
break;
1915-
}
1916-
}
1914+
} while (_Val > _Yx1);
19171915
_Res = _Res << (_Wx0 + 1) | (static_cast<result_type>(_Val) & _Mask);
19181916
}
19191917
return _Res;
@@ -1965,8 +1963,14 @@ private:
19651963
_Nx = (_Wx + _Mx - 1) / _Mx + _Nfix; // trial _Nx
19661964
_Wx0 = _Wx / _Nx;
19671965
_Nx0 = _Nx - _Wx % _Nx;
1968-
_Yx0 = (_Rx >> _Wx0) << _Wx0;
1969-
_Yx1 = (((_Rx >> _Wx0) >> 1) << _Wx0) << 1;
1966+
if (_Wx0 < sizeof(_Eres) * CHAR_BIT) {
1967+
_Yx0 = (_Rx >> _Wx0) << _Wx0;
1968+
_Yx1 = (((_Rx >> _Wx0) >> 1) << _Wx0) << 1;
1969+
} else {
1970+
_Yx0 = 0;
1971+
_Yx1 = 0;
1972+
}
1973+
19701974
if (_Nfix == 1 || _Rx - _Yx0 <= _Yx0 / _Nx) {
19711975
break; // also works if _Rx == 0 (_Mx == all bits)
19721976
}

0 commit comments

Comments
 (0)