* [PATCH] PR libstdc++/85494 use rand_s in std::random_device
@ 2019-06-27 11:35 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2019-06-27 11:35 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 967 bytes --]
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.
Tested x86_64-pc-linux-gnu and x86_64-w64-mingw32, committed to
gcc-9-branch.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 5469 bytes --]
commit f055311955f357f567cd38d2fe8da2af16c1c3ae
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu Jun 27 11:31:02 2019 +0000
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-9-branch@272748 138bc75d-0d04-0410-961f-82ee72b054a4
diff --git a/libstdc++-v3/config/os/mingw32-w64/os_defines.h b/libstdc++-v3/config/os/mingw32-w64/os_defines.h
index 6c19d3953a6..418c6f569df 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 c36f297438e..a5e4ad29dc3 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 1146d21c3f9..0bb6b6bf5b8 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 00000000000..2670ad7225a
--- /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();
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2019-06-27 11:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-27 11:35 [PATCH] PR libstdc++/85494 use rand_s in std::random_device Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).