[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