@@ -88,4 +88,6 @@
// See libstdc++/59807
#define _GTHREAD_USE_MUTEX_INIT_FUNC 1
+#define _GLIBCXX_USE_CRT_RAND_S 1
+
#endif
@@ -77,8 +77,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
}
void
- random_device::_M_init_pretr1(const std::string& token)
+ random_device::_M_init_pretr1(const std::string& token [[gnu::unused]])
{
+#ifndef _GLIBCXX_USE_CRT_RAND_S
unsigned long __seed = 5489UL;
if (token != "mt19937")
{
@@ -90,6 +91,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
"(const std::string&)"));
}
_M_mt.seed(__seed);
+#endif
}
} // namespace
#endif
@@ -23,6 +23,8 @@
// <http://www.gnu.org/licenses/>.
#define _GLIBCXX_USE_CXX11_ABI 1
+#define _CRT_RAND_S // define this before including <stdlib.h> to get rand_s
+
#include <random>
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
@@ -50,6 +52,10 @@
# include <linux/random.h>
#endif
+#ifdef _GLIBCXX_USE_CRT_RAND_S
+# include <stdlib.h>
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
namespace
@@ -85,6 +91,18 @@ namespace std _GLIBCXX_VISIBILITY(default)
return val;
}
#endif
+
+#ifdef _GLIBCXX_USE_CRT_RAND_S
+# pragma GCC poison _M_mt
+ unsigned int
+ __winxp_rand_s()
+ {
+ unsigned int val;
+ if (::rand_s(&val) != 0)
+ std::__throw_runtime_error(__N("random_device: rand_s failed"));
+ return val;
+ }
+#endif
}
void
@@ -122,9 +140,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
}
void
- random_device::_M_init_pretr1(const std::string& token)
+ random_device::_M_init_pretr1(const std::string& token [[gnu::unused]])
{
+#ifndef _GLIBCXX_USE_CRT_RAND_S
_M_mt.seed(_M_strtoul(token));
+#endif
}
void
@@ -170,7 +190,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
random_device::result_type
random_device::_M_getval_pretr1()
{
+#ifdef _GLIBCXX_USE_CRT_RAND_S
+ return __winxp_rand_s();
+#else
return _M_mt();
+#endif
}
double
new file mode 100644
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// { dg-require-effective-target random_device }
+
+#include <random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ unsigned v1[3], v2[3];
+ std::random_device d1, d2;
+ for (auto& v : v1)
+ v = d1();
+ for (auto& v : v2)
+ v = d2();
+ VERIFY (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2] );
+}
+
+int
+main()
+{
+ test01();
+}