[libcxx-commits] [libcxx] [libc++] Use glibc random APIs for std::random_device on Linux (PR #222567)

QIU Chaofan via libcxx-commits libcxx-commits at lists.llvm.org
Tue Nov 3 00:28:03 PST 2026


https://github.com/ecnelises updated https://github.com/llvm/llvm-project/pull/222567

>From e7f5aaee64a3db73762ca3bc6e7b6f689f2a1f90 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qcf at ecnelises.com>
Date: Thu, 10 Sep 2026 17:36:57 +0800
Subject: [PATCH] [libc++] Use glibc random APIs for std::random_device on
 Linux

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.
---
 libcxx/docs/ReleaseNotes/24.rst               |  4 +++
 libcxx/include/__config                       |  8 ++++++
 libcxx/include/__random/random_device.h       |  8 +++---
 .../rand/rand.device/abi.compile.pass.cpp     | 27 +++++++++++++++++++
 .../numerics/rand/rand.device/ctor.pass.cpp   |  1 +
 .../numerics/rand/rand.device/eval.pass.cpp   |  1 +
 .../libcxx/test/features/libcxx_macros.py     |  1 +
 7 files changed, 46 insertions(+), 4 deletions(-)
 create mode 100644 libcxx/test/libcxx/numerics/rand/rand.device/abi.compile.pass.cpp

diff --git a/libcxx/docs/ReleaseNotes/24.rst b/libcxx/docs/ReleaseNotes/24.rst
index 04f02ab66a773c..fc528a15f3fe2b 100644
--- a/libcxx/docs/ReleaseNotes/24.rst
+++ b/libcxx/docs/ReleaseNotes/24.rst
@@ -72,6 +72,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 ade43d42dc283d..5a0700a2ce5374 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__)
+#    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/__random/random_device.h b/libcxx/include/__random/random_device.h
index f28e5fca140e56..28e53d746a32db 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/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 00000000000000..4d450149a9c597
--- /dev/null
+++ b/libcxx/test/libcxx/numerics/rand/rand.device/abi.compile.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, libcpp-abi-no-random-device-compatibility-layout
+
+// Ensure layout of std::random_device is compatible.
+
+#include <random>
+
+#include "test_macros.h"
+
+#if defined(_LIBCPP_USING_DEV_RANDOM) || 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/std/numerics/rand/rand.device/ctor.pass.cpp b/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp
index 6db61479e041f2..4d22d968b3d7fc 100644
--- a/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp
@@ -11,6 +11,7 @@
 // XFAIL: target={{.+}}-apple-{{.+}} && using-built-library-before-llvm-14
 
 // UNSUPPORTED: no-random-device
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
 
 // <random>
 
diff --git a/libcxx/test/std/numerics/rand/rand.device/eval.pass.cpp b/libcxx/test/std/numerics/rand/rand.device/eval.pass.cpp
index 9c385b3b88ec72..478a9130d60ef2 100644
--- a/libcxx/test/std/numerics/rand/rand.device/eval.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.device/eval.pass.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: no-random-device
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
 
 // <random>
 
diff --git a/libcxx/utils/libcxx/test/features/libcxx_macros.py b/libcxx/utils/libcxx/test/features/libcxx_macros.py
index 38f761af009a7b..067d73d7d37ca6 100644
--- a/libcxx/utils/libcxx/test/features/libcxx_macros.py
+++ b/libcxx/utils/libcxx/test/features/libcxx_macros.py
@@ -36,6 +36,7 @@
     "_LIBCPP_PSTL_BACKEND_LIBDISPATCH": "libcpp-pstl-backend-libdispatch",
     "_LIBCPP_ABI_USE_SMALL_DEQUE_BLOCK_SIZE": "libcpp-abi-use-small-deque-block-size",
     "_LIBCPP_ABI_COMPACT_LOCALE_ID": "libcpp-abi-compact-locale-id",
+    "_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT": "libcpp-abi-no-random-device-compatibility-layout",
 }
 for macro, feature in macros.items():
     features.append(



More information about the libcxx-commits mailing list