]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/51795 (linear_congruential_engine doesn't work correctly)
authorPaolo Carlini <paolo.carlini@oracle.com>
Wed, 1 Feb 2012 11:10:30 +0000 (11:10 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 1 Feb 2012 11:10:30 +0000 (11:10 +0000)
2012-02-01  Paolo Carlini  <paolo.carlini@oracle.com>

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: r183795

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/random.h
libstdc++-v3/include/bits/random.tcc

index 7036b53c4892f5f93c1c062dade94f433dd41257..5dc5c06444abba1f54a145e0efcab73ad38062ba 100644 (file)
@@ -1,3 +1,12 @@
+2012-02-01  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR libstdc++/51795
+       * include/bits/random.h (linear_congruential_generator): Add
+       static_assert preventing instantiation for values of 'a' and 'm'
+       currently handled incorrectly by _Mod::__calc.
+       * include/bits/random.tcc (seed_seq::generate): Avoid unsafe
+       uses of _Mod::__calc.
+
 2012-01-03  Chase Douglas  <chase.douglas@canonical.com>
            Jonathan Wakely  <jwakely.gcc@gmail.com>
 
index 988ee61cab25384c1523c43bad884e19a59c6fd8..79e8e35c37d8c089e4e93a12721712c3047333ac 100644 (file)
@@ -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;
index b9f6af6536240341f6654b3a87ef385185d4ab6d..89885741d57b50a4d40021b79bc60a6615648bed 100644 (file)
@@ -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<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool>
       struct _Mod
       {
@@ -2769,8 +2771,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;
@@ -2791,8 +2793,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);