[gcc/devel/omp/gcc-9] PR libstdc++/85494 use rand_s in std::random_device
Tobias Burnus
burnus@gcc.gnu.org
Thu Mar 5 14:03:00 GMT 2020
https://gcc.gnu.org/g:0e7ffed96cfdde1f9c37fb9305785b507141047b
commit 0e7ffed96cfdde1f9c37fb9305785b507141047b
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Jun 27 12:31:02 2019 +0100
PR libstdc++/85494 use rand_s in std::random_device
This is a minimal fix for the use of a deterministic RNG on mingw-w64,
simply using rand_s unconditionally. The rest of the r271740 changes on
trunk are not included. That means that RDSEED and RDRAND are not
available for mingw-w64 and the token passed to the constructor is
ignored completely.
PR libstdc++/85494 use rand_s in std::random_device
* config/os/mingw32-w64/os_defines.h (_GLIBCXX_USE_CRT_RAND_S): Define.
* src/c++11/cow-string-inst.cc (random_device::_M_init_pretr1)
[_GLIBCXX_USE_CRT_RAND_S]: Do nothing if rand_s will be used.
* src/c++11/random.cc [_GLIBCXX_USE_CRT_RAND_S] (__winxp_rand_s):
Define new function.
(random_device::_M_init_pretr1) [_GLIBCXX_USE_CRT_RAND_S]: Do nothing
if rand_s will be used.
(random_device::_M_getval_pretr1) [_GLIBCXX_USE_CRT_RAND_S]: Use
__winxp_rand_s().
* testsuite/26_numerics/random/random_device/85494.cc: New test.
From-SVN: r272748
Diff:
---
libstdc++-v3/ChangeLog | 12 +++++++
libstdc++-v3/config/os/mingw32-w64/os_defines.h | 2 ++
libstdc++-v3/src/c++11/cow-string-inst.cc | 4 ++-
libstdc++-v3/src/c++11/random.cc | 26 +++++++++++++-
.../26_numerics/random/random_device/85494.cc | 40 ++++++++++++++++++++++
5 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index e641f0e..1ca540f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,17 @@
2019-06-27 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/85494 use rand_s in std::random_device
+ * config/os/mingw32-w64/os_defines.h (_GLIBCXX_USE_CRT_RAND_S): Define.
+ * src/c++11/cow-string-inst.cc (random_device::_M_init_pretr1)
+ [_GLIBCXX_USE_CRT_RAND_S]: Do nothing if rand_s will be used.
+ * src/c++11/random.cc [_GLIBCXX_USE_CRT_RAND_S] (__winxp_rand_s):
+ Define new function.
+ (random_device::_M_init_pretr1) [_GLIBCXX_USE_CRT_RAND_S]: Do nothing
+ if rand_s will be used.
+ (random_device::_M_getval_pretr1) [_GLIBCXX_USE_CRT_RAND_S]: Use
+ __winxp_rand_s().
+ * testsuite/26_numerics/random/random_device/85494.cc: New test.
+
PR libstdc++/91012
* src/c++17/fs_path.cc (filesystem_error::_Impl): Use a string_view
for the what_arg parameters.
diff --git a/libstdc++-v3/config/os/mingw32-w64/os_defines.h b/libstdc++-v3/config/os/mingw32-w64/os_defines.h
index 6c19d39..418c6f5 100644
--- a/libstdc++-v3/config/os/mingw32-w64/os_defines.h
+++ b/libstdc++-v3/config/os/mingw32-w64/os_defines.h
@@ -88,4 +88,6 @@
// See libstdc++/59807
#define _GTHREAD_USE_MUTEX_INIT_FUNC 1
+#define _GLIBCXX_USE_CRT_RAND_S 1
+
#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index c36f297..a5e4ad2 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -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
diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index 1146d21..0bb6b6b 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/85494.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/85494.cc
new file mode 100644
index 0000000..2670ad7
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/85494.cc
@@ -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();
+}
More information about the Libstdc++-cvs
mailing list