From d9c257a7e22e482f4ac01f53e09e3895c424e24a Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 27 Jan 2012 23:30:28 +0000 Subject: [PATCH] re PR libstdc++/51795 (linear_congruential_engine doesn't work correctly) 2012-01-27 Paolo Carlini PR libstdc++/51795 * include/bits/random.h (linear_congruential_generator): Add static_assert preventing instantiation for values of 'a' and 'm' currently handled incorrectly but _Mod::__calc. * include/bits/random.tcc (seed_seq::generate): Avoid unsafe uses of _Mod::__calc. From-SVN: r183655 --- libstdc++-v3/ChangeLog | 9 +++++++++ libstdc++-v3/include/bits/random.h | 7 ++++++- libstdc++-v3/include/bits/random.tcc | 12 +++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2dbb665a345..82dbf42f96a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2012-01-27 Paolo Carlini + + PR libstdc++/51795 + * include/bits/random.h (linear_congruential_generator): Add + static_assert preventing instantiation for values of 'a' and 'm' + currently handled incorrectly but _Mod::__calc. + * include/bits/random.tcc (seed_seq::generate): Avoid unsafe + uses of _Mod::__calc. + 2012-01-27 Jakub Jelinek PR libstdc++/51798 diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h index d109224d1bf..8f6bf4f7bd5 100644 --- a/libstdc++-v3/include/bits/random.h +++ b/libstdc++-v3/include/bits/random.h @@ -1,6 +1,6 @@ // random number generation -*- C++ -*- -// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -174,6 +174,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(__m == 0u || (__a < __m && __c < __m), "template argument substituting __m out of bounds"); + // XXX FIXME: + // _Mod::__calc should handle correctly __m % __a >= __m / __a too. + static_assert(__m % __a < __m / __a, + "sorry, not implemented yet: try a smaller 'a' constant"); + public: /** The type of the generated random value. */ typedef _UIntType result_type; diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc index 8936a62316a..d55b51838b8 100644 --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -1,6 +1,6 @@ // random number generation (out of line) -*- C++ -*- -// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -49,6 +49,8 @@ namespace std _GLIBCXX_VISIBILITY(default) // // Preconditions: a > 0, m > 0. // + // XXX FIXME: as-is, only works correctly for __m % __a < __m / __a. + // template struct _Mod { @@ -2771,8 +2773,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ^ __begin[(__k + __p) % __n] ^ __begin[(__k - 1) % __n]); _Type __r1 = __arg ^ (__arg >> 27); - __r1 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value, - 1664525u, 0u>(__r1); + __r1 = __detail::__mod<_Type, + __detail::_Shift<_Type, 32>::__value>(1664525u * __r1); _Type __r2 = __r1; if (__k == 0) __r2 += __s; @@ -2793,8 +2795,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + __begin[(__k + __p) % __n] + __begin[(__k - 1) % __n]); _Type __r3 = __arg ^ (__arg >> 27); - __r3 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value, - 1566083941u, 0u>(__r3); + __r3 = __detail::__mod<_Type, + __detail::_Shift<_Type, 32>::__value>(1566083941u * __r3); _Type __r4 = __r3 - __k % __n; __r4 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value>(__r4);