aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog16
-rw-r--r--libstdc++-v3/include/bits/random.h2
-rw-r--r--libstdc++-v3/src/c++11/cow-string-inst.cc50
-rw-r--r--libstdc++-v3/src/c++11/random.cc12
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default-cow.cc38
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc10
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc16
7 files changed, 86 insertions, 58 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index cd535fe..71ef811 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,19 @@
+2019-05-31 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/random.h (random_device::_M_init(const char*, size_t)):
+ Add new private member function.
+ * src/c++11/cow-string-inst.cc (random_device::_M_init(const string&))
+ (random_device::_M_init_pretr1(const string&)): Call new private
+ member with string data.
+ * src/c++11/random.cc (random_device::_M_init(const char*, size_t)):
+ Define.
+ * testsuite/26_numerics/random/random_device/cons/default-cow.cc: New
+ test using COW strings.
+ * testsuite/26_numerics/random/random_device/cons/default.cc: Generate
+ a value from the device.
+ * testsuite/26_numerics/random/random_device/cons/token.cc: Likewise.
+ Fix typo in token string.
+
2019-05-30 Nina Dinka Ranns <dinka.ranns@gmail.com>
LWG2788 basic_string spurious use of a default constructible allocator
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index 9c959d6..e63dbcf 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -1648,6 +1648,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
result_type _M_getval_pretr1();
double _M_getentropy() const noexcept;
+ void _M_init(const char*, size_t); // not exported from the shared library
+
union
{
struct
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index c36f297..107a457 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -35,61 +35,15 @@
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
#include <random>
-#if defined __i386__ || defined __x86_64__
-# include <cpuid.h>
-#endif
-#include <cstdio>
namespace std _GLIBCXX_VISIBILITY(default)
{
void
random_device::_M_init(const std::string& token)
- {
- const char *fname = token.c_str();
-
- if (token == "default")
- {
-#if (defined __i386__ || defined __x86_64__) && defined _GLIBCXX_X86_RDRAND
- unsigned int eax, ebx, ecx, edx;
- // Check availability of cpuid and, for now at least, also the
- // CPU signature for Intel's
- if (__get_cpuid_max(0, &ebx) > 0 && ebx == signature_INTEL_ebx)
- {
- __cpuid(1, eax, ebx, ecx, edx);
- if (ecx & bit_RDRND)
- {
- _M_file = nullptr;
- return;
- }
- }
-#endif
-
- fname = "/dev/urandom";
- }
- else if (token != "/dev/urandom" && token != "/dev/random")
- fail:
- std::__throw_runtime_error(__N("random_device::"
- "random_device(const std::string&)"));
-
- _M_file = static_cast<void*>(std::fopen(fname, "rb"));
- if (!_M_file)
- goto fail;
- }
+ { _M_init(token.c_str(), token.length()); }
void
random_device::_M_init_pretr1(const std::string& token)
- {
- unsigned long __seed = 5489UL;
- if (token != "mt19937")
- {
- const char* __nptr = token.c_str();
- char* __endptr;
- __seed = std::strtoul(__nptr, &__endptr, 0);
- if (*__nptr == '\0' || *__endptr != '\0')
- std::__throw_runtime_error(__N("random_device::random_device"
- "(const std::string&)"));
- }
- _M_mt.seed(__seed);
- }
+ { _M_init(token.c_str(), token.length()); }
} // namespace
#endif
diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc
index 85cb2df..10fbe1d 100644
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -293,6 +293,18 @@ namespace std _GLIBCXX_VISIBILITY(default)
#endif
}
+ // Called by old ABI version of random_device::_M_init(const std::string&).
+ void
+ random_device::_M_init(const char* s, size_t len)
+ {
+ const std::string token(s, len);
+#ifdef USE_MT19937
+ _M_init_pretr1(token);
+#else
+ _M_init(token);
+#endif
+ }
+
void
random_device::_M_fini()
{
diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default-cow.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default-cow.cc
new file mode 100644
index 0000000..622801d
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default-cow.cc
@@ -0,0 +1,38 @@
+// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
+// { dg-do run { target c++11 } }
+// { dg-require-effective-target random_device }
+// { dg-require-cstdint "" }
+//
+// 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/>.
+
+// C++11 26.5.6 class random_device [rand.device]
+
+#include <random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::random_device x;
+ auto n [[gnu::unused]] = x();
+}
+
+int main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc
index 4fa1adf..ed03c54 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc
@@ -21,8 +21,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 26.4.6 class random_device [rand.device]
-// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
+// C++11 26.5.6 class random_device [rand.device]
#include <random>
#include <testsuite_hooks.h>
@@ -32,8 +31,11 @@ test01()
{
std::random_device x;
- VERIFY( x.min() == std::numeric_limits<std::random_device::result_type>::min() );
- VERIFY( x.max() == std::numeric_limits<std::random_device::result_type>::max() );
+ using result_type = std::random_device::result_type;
+ VERIFY( x.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( x.max() == std::numeric_limits<result_type>::max() );
+
+ result_type n [[gnu::unused]] = x();
}
int main()
diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc
index cf5e81e..31a86b0 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/token.cc
@@ -30,10 +30,9 @@ void
test01()
{
std::random_device x("default");
-
- VERIFY( x.min() == std::numeric_limits<std::random_device::result_type>::min() );
- VERIFY( x.max() == std::numeric_limits<std::random_device::result_type>::max() );
-
+ using result_type = std::random_device::result_type;
+ VERIFY( x.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( x.max() == std::numeric_limits<result_type>::max() );
}
void
@@ -42,6 +41,7 @@ test02()
#ifdef _GLIBCXX_USE_DEV_RANDOM
std::random_device x1("/dev/urandom");
std::random_device x2("/dev/random");
+ VERIFY( x1() != x2() );
#endif
}
@@ -50,7 +50,7 @@ test03()
{
// At least one of these tokens should be valid.
const std::string tokens[] = {
- "rdseed", "rdrand", "rand_s", "/dev/urandom", "/dev/random", "mt19337"
+ "rdseed", "rdrand", "rand_s", "/dev/urandom", "/dev/random", "mt19937"
};
int count = 0;
for (const std::string& token : tokens)
@@ -71,21 +71,25 @@ void
test04()
{
bool can_use_mt19937 = true;
+ std::random_device::result_type xval;
try
{
std::random_device x("mt19937");
+ xval = x();
}
catch (const std::runtime_error&)
{
can_use_mt19937 = false;
}
- // If "mt19337" is a valid token then numeric seeds should be too.
+ // If "mt19937" is a valid token then numeric seeds should be too.
if (can_use_mt19937)
{
std::random_device x1("0");
std::random_device x2("1234");
std::random_device x3("0xc0fefe");
+ VERIFY( xval != x1() );
+ VERIFY( x2() != x3() );
}
}