[libcxx-commits] [libcxx] [libc++] Use glibc random APIs for std::random_device on Linux (PR #222567)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Sep 10 02:43:00 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: QIU Chaofan (ecnelises)
<details>
<summary>Changes</summary>
Use arc4random with glibc 2.36 and later, and getentropy with glibc 2.25 through 2.35. Retain current urandom file based implementation on other Linux libc and older glibc versions.
---
Full diff: https://github.com/llvm/llvm-project/pull/222567.diff
7 Files Affected:
- (modified) libcxx/docs/ReleaseNotes/24.rst (+4)
- (modified) libcxx/include/__config (+8)
- (modified) libcxx/include/__cxx03/__config (+8)
- (modified) libcxx/include/__cxx03/__random/random_device.h (+4-4)
- (modified) libcxx/include/__random/random_device.h (+4-4)
- (added) libcxx/test/libcxx-03/numerics/rand/rand.device/abi.compile.pass.cpp (+28)
- (added) libcxx/test/libcxx/numerics/rand/rand.device/abi.compile.pass.cpp (+28)
``````````diff
diff --git a/libcxx/docs/ReleaseNotes/24.rst b/libcxx/docs/ReleaseNotes/24.rst
index a7b9e8731d555..ee3b7ef7c60a4 100644
--- a/libcxx/docs/ReleaseNotes/24.rst
+++ b/libcxx/docs/ReleaseNotes/24.rst
@@ -67,6 +67,10 @@ Deprecations and Removals
Potentially breaking changes
----------------------------
+- On Linux, ``std::random_device`` now uses ``arc4random`` when libc++ is built against glibc 2.36+, and ``getentropy``
+ when built against glibc 2.25 through 2.35, instead of reading from ``/dev/urandom``. Behavior with older glibc versions
+ and other C libraries on Linux remain unchanged.
+
- In LLVM 23, libc++ dropped a lot of transitive includes in all language modes. This improves compile time significantly,
but causes programs which rely on these includes to not compile anymore. The ``_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23``
macro that was provided in LLVM 23 to ease the transition has been removed in this release.
diff --git a/libcxx/include/__config b/libcxx/include/__config
index e98aea7be8531..2383840a27f57 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -85,6 +85,14 @@
# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
defined(__DragonFly__) || defined(__BIONIC__)
# define _LIBCPP_USING_ARC4_RANDOM
+# elif defined(__linux__) && defined(_LIBCPP_GLIBC_PREREQ)
+# if _LIBCPP_GLIBC_PREREQ(2, 36)
+# define _LIBCPP_USING_ARC4_RANDOM
+# elif _LIBCPP_GLIBC_PREREQ(2, 25)
+# define _LIBCPP_USING_GETENTROPY
+# else
+# define _LIBCPP_USING_DEV_RANDOM
+# endif
# elif defined(__wasi__) || defined(__EMSCRIPTEN__)
# define _LIBCPP_USING_GETENTROPY
# elif defined(__Fuchsia__)
diff --git a/libcxx/include/__cxx03/__config b/libcxx/include/__cxx03/__config
index 46c7c4440e7b9..7bcc2ea2ceafa 100644
--- a/libcxx/include/__cxx03/__config
+++ b/libcxx/include/__cxx03/__config
@@ -265,6 +265,14 @@ _LIBCPP_HARDENING_MODE_DEBUG
# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
defined(__DragonFly__) || defined(__BIONIC__)
# define _LIBCPP_USING_ARC4_RANDOM
+# elif defined(__linux__) && defined(_LIBCPP_GLIBC_PREREQ)
+# if _LIBCPP_GLIBC_PREREQ(2, 36)
+# define _LIBCPP_USING_ARC4_RANDOM
+# elif _LIBCPP_GLIBC_PREREQ(2, 25)
+# define _LIBCPP_USING_GETENTROPY
+# else
+# define _LIBCPP_USING_DEV_RANDOM
+# endif
# elif defined(__wasi__) || defined(__EMSCRIPTEN__)
# define _LIBCPP_USING_GETENTROPY
# elif defined(__Fuchsia__)
diff --git a/libcxx/include/__cxx03/__random/random_device.h b/libcxx/include/__cxx03/__random/random_device.h
index f898c072b023e..9a79aaefed354 100644
--- a/libcxx/include/__cxx03/__random/random_device.h
+++ b/libcxx/include/__cxx03/__random/random_device.h
@@ -30,10 +30,10 @@ class _LIBCPP_EXPORTED_FROM_ABI random_device {
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
- // Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now
- // use `arc4random()` as of this comment. In order to avoid breaking the ABI, we
- // retain the same layout as before.
-# if defined(__APPLE__)
+ // Apple platforms and GNU/Linux used to use the `_LIBCPP_USING_DEV_RANDOM`
+ // code path, and now use `arc4random` or `getentropy`. In order to avoid
+ // breaking the ABI, we retain the same layout as before.
+# if defined(__APPLE__) || defined(__GLIBC__)
int __padding_; // padding to fake the `__f_` field above
# endif
diff --git a/libcxx/include/__random/random_device.h b/libcxx/include/__random/random_device.h
index f28e5fca140e5..28e53d746a32d 100644
--- a/libcxx/include/__random/random_device.h
+++ b/libcxx/include/__random/random_device.h
@@ -28,10 +28,10 @@ class _LIBCPP_EXPORTED_FROM_ABI random_device {
# ifdef _LIBCPP_USING_DEV_RANDOM
int __f_;
# elif !defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT)
- // Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now
- // use `arc4random()` as of this comment. In order to avoid breaking the ABI, we
- // retain the same layout as before.
-# if defined(__APPLE__)
+ // Apple platforms and GNU/Linux used to use the `_LIBCPP_USING_DEV_RANDOM`
+ // code path, and now use `arc4random` or `getentropy`. In order to avoid
+ // breaking the ABI, we retain the same layout as before.
+# if defined(__APPLE__) || defined(__GLIBC__)
[[__maybe_unused__]] int __padding_; // padding to fake the `__f_` field above
# endif
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.device/abi.compile.pass.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.device/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..9106d6e058b14
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.device/abi.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-random-device
+
+// Ensure layout of std::random_device is compatible.
+
+#include <random>
+
+#include "test_macros.h"
+
+#if defined(_LIBCPP_USING_DEV_RANDOM) || \
+ (!defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT) && (defined(__APPLE__) || defined(__GLIBC__)))
+
+static_assert(sizeof(std::random_device) == sizeof(int), "");
+static_assert(TEST_ALIGNOF(std::random_device) == TEST_ALIGNOF(int), "");
+
+#else
+
+static_assert(sizeof(std::random_device) == 1, "");
+static_assert(TEST_ALIGNOF(std::random_device) == 1, "");
+
+#endif
diff --git a/libcxx/test/libcxx/numerics/rand/rand.device/abi.compile.pass.cpp b/libcxx/test/libcxx/numerics/rand/rand.device/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..9106d6e058b14
--- /dev/null
+++ b/libcxx/test/libcxx/numerics/rand/rand.device/abi.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-random-device
+
+// Ensure layout of std::random_device is compatible.
+
+#include <random>
+
+#include "test_macros.h"
+
+#if defined(_LIBCPP_USING_DEV_RANDOM) || \
+ (!defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT) && (defined(__APPLE__) || defined(__GLIBC__)))
+
+static_assert(sizeof(std::random_device) == sizeof(int), "");
+static_assert(TEST_ALIGNOF(std::random_device) == TEST_ALIGNOF(int), "");
+
+#else
+
+static_assert(sizeof(std::random_device) == 1, "");
+static_assert(TEST_ALIGNOF(std::random_device) == 1, "");
+
+#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/222567
More information about the libcxx-commits
mailing list