mirror of git://gcc.gnu.org/git/gcc.git
re PR libstdc++/52699 (infinite loop generated with -O0)
2012-04-14 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/52699 * include/bits/random.tcc (independent_bits_engine<>::operator()()) Avoid various overflows; use common_type on result_type and _RandomNumberEngine::result_type; avoid floating point computations; other smaller tweaks. * include/bits/random.tcc (uniform_int_distribution<>::operator()) Use common_type; assume _UniformRandomNumberGenerator::result_type unsigned; tidy. * include/bits/stl_algobase.h (__lg(unsigned), __lg(unsigned long), __lg(unsigned long long)): Add. From-SVN: r186456
This commit is contained in:
parent
608dccd7ab
commit
f84ca6e7ce
|
@ -1,3 +1,18 @@
|
||||||
|
2012-04-14 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
|
PR libstdc++/52699
|
||||||
|
* include/bits/random.tcc (independent_bits_engine<>::operator()())
|
||||||
|
Avoid various overflows; use common_type on result_type and
|
||||||
|
_RandomNumberEngine::result_type; avoid floating point computations;
|
||||||
|
other smaller tweaks.
|
||||||
|
|
||||||
|
* include/bits/random.tcc (uniform_int_distribution<>::operator())
|
||||||
|
Use common_type; assume _UniformRandomNumberGenerator::result_type
|
||||||
|
unsigned; tidy.
|
||||||
|
|
||||||
|
* include/bits/stl_algobase.h (__lg(unsigned), __lg(unsigned long),
|
||||||
|
__lg(unsigned long long)): Add.
|
||||||
|
|
||||||
2012-04-14 Alan Modra <amodra@gmail.com>
|
2012-04-14 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR libstdc++/52839
|
PR libstdc++/52839
|
||||||
|
|
|
@ -730,40 +730,65 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
|
independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
|
||||||
operator()()
|
operator()()
|
||||||
{
|
{
|
||||||
const long double __r = static_cast<long double>(_M_b.max())
|
typedef typename _RandomNumberEngine::result_type _Eresult_type;
|
||||||
- static_cast<long double>(_M_b.min()) + 1.0L;
|
const _Eresult_type __r
|
||||||
const result_type __m = std::log(__r) / std::log(2.0L);
|
= (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max()
|
||||||
result_type __n, __n0, __y0, __y1, __s0, __s1;
|
? _M_b.max() - _M_b.min() + 1 : 0);
|
||||||
|
const unsigned __edig = std::numeric_limits<_Eresult_type>::digits;
|
||||||
|
const unsigned __m = __r ? std::__lg(__r) : __edig;
|
||||||
|
|
||||||
|
typedef typename std::common_type<_Eresult_type, result_type>::type
|
||||||
|
__ctype;
|
||||||
|
const unsigned __cdig = std::numeric_limits<__ctype>::digits;
|
||||||
|
|
||||||
|
unsigned __n, __n0;
|
||||||
|
__ctype __s0, __s1, __y0, __y1;
|
||||||
|
|
||||||
for (size_t __i = 0; __i < 2; ++__i)
|
for (size_t __i = 0; __i < 2; ++__i)
|
||||||
{
|
{
|
||||||
__n = (__w + __m - 1) / __m + __i;
|
__n = (__w + __m - 1) / __m + __i;
|
||||||
__n0 = __n - __w % __n;
|
__n0 = __n - __w % __n;
|
||||||
const result_type __w0 = __w / __n;
|
const unsigned __w0 = __w / __n; // __w0 <= __m
|
||||||
const result_type __w1 = __w0 + 1;
|
|
||||||
__s0 = result_type(1) << __w0;
|
__s0 = 0;
|
||||||
__s1 = result_type(1) << __w1;
|
__s1 = 0;
|
||||||
__y0 = __s0 * (__r / __s0);
|
if (__w0 < __cdig)
|
||||||
__y1 = __s1 * (__r / __s1);
|
{
|
||||||
if (__r - __y0 <= __y0 / __n)
|
__s0 = __ctype(1) << __w0;
|
||||||
|
__s1 = __s0 << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__y0 = 0;
|
||||||
|
__y1 = 0;
|
||||||
|
if (__r)
|
||||||
|
{
|
||||||
|
__y0 = __s0 * (__r / __s0);
|
||||||
|
if (__s1)
|
||||||
|
__y1 = __s1 * (__r / __s1);
|
||||||
|
|
||||||
|
if (__r - __y0 <= __y0 / __n)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_type __sum = 0;
|
result_type __sum = 0;
|
||||||
for (size_t __k = 0; __k < __n0; ++__k)
|
for (size_t __k = 0; __k < __n0; ++__k)
|
||||||
{
|
{
|
||||||
result_type __u;
|
__ctype __u;
|
||||||
do
|
do
|
||||||
__u = _M_b() - _M_b.min();
|
__u = _M_b() - _M_b.min();
|
||||||
while (__u >= __y0);
|
while (__y0 && __u >= __y0);
|
||||||
__sum = __s0 * __sum + __u % __s0;
|
__sum = __s0 * __sum + (__s0 ? __u % __s0 : __u);
|
||||||
}
|
}
|
||||||
for (size_t __k = __n0; __k < __n; ++__k)
|
for (size_t __k = __n0; __k < __n; ++__k)
|
||||||
{
|
{
|
||||||
result_type __u;
|
__ctype __u;
|
||||||
do
|
do
|
||||||
__u = _M_b() - _M_b.min();
|
__u = _M_b() - _M_b.min();
|
||||||
while (__u >= __y1);
|
while (__y1 && __u >= __y1);
|
||||||
__sum = __s1 * __sum + __u % __s1;
|
__sum = __s1 * __sum + (__s1 ? __u % __s1 : __u);
|
||||||
}
|
}
|
||||||
return __sum;
|
return __sum;
|
||||||
}
|
}
|
||||||
|
@ -840,12 +865,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
operator()(_UniformRandomNumberGenerator& __urng,
|
operator()(_UniformRandomNumberGenerator& __urng,
|
||||||
const param_type& __param)
|
const param_type& __param)
|
||||||
{
|
{
|
||||||
typedef typename std::make_unsigned<typename
|
typedef typename _UniformRandomNumberGenerator::result_type
|
||||||
_UniformRandomNumberGenerator::result_type>::type __urngtype;
|
_Gresult_type;
|
||||||
typedef typename std::make_unsigned<result_type>::type __utype;
|
typedef typename std::make_unsigned<result_type>::type __utype;
|
||||||
typedef typename std::conditional<(sizeof(__urngtype)
|
typedef typename std::common_type<_Gresult_type, __utype>::type
|
||||||
> sizeof(__utype)),
|
__uctype;
|
||||||
__urngtype, __utype>::type __uctype;
|
|
||||||
|
|
||||||
const __uctype __urngmin = __urng.min();
|
const __uctype __urngmin = __urng.min();
|
||||||
const __uctype __urngmax = __urng.max();
|
const __uctype __urngmax = __urng.max();
|
||||||
|
|
|
@ -989,14 +989,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
__lg(int __n)
|
__lg(int __n)
|
||||||
{ return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); }
|
{ return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); }
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
__lg(unsigned __n)
|
||||||
|
{ return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); }
|
||||||
|
|
||||||
inline long
|
inline long
|
||||||
__lg(long __n)
|
__lg(long __n)
|
||||||
{ return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); }
|
{ return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); }
|
||||||
|
|
||||||
|
inline unsigned long
|
||||||
|
__lg(unsigned long __n)
|
||||||
|
{ return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); }
|
||||||
|
|
||||||
inline long long
|
inline long long
|
||||||
__lg(long long __n)
|
__lg(long long __n)
|
||||||
{ return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
|
{ return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
|
||||||
|
|
||||||
|
inline unsigned long long
|
||||||
|
__lg(unsigned long long __n)
|
||||||
|
{ return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_VERSION
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
|
||||||
_GLIBCXX_BEGIN_NAMESPACE_ALGO
|
_GLIBCXX_BEGIN_NAMESPACE_ALGO
|
||||||
|
|
Loading…
Reference in New Issue