[libcxx-commits] [libcxx] [libc++] Enable C++ stdatomic.h for all C++ versions (PR #95498)

Ryan Prichard via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 14 19:45:55 PDT 2024


https://github.com/rprichard updated https://github.com/llvm/llvm-project/pull/95498

>From ac50370374a417381f3214fbab2fa0707fe22498 Mon Sep 17 00:00:00 2001
From: Ryan Prichard <rprichard at google.com>
Date: Mon, 10 Jun 2024 19:24:52 -0700
Subject: [PATCH 1/2] [libc++] Enable C++ stdatomic.h for all C++ versions

This extension is motivated by Android's use of libc++, where
<stdatomic.h> has redirected to <atomic> for many years, long before it
was standardized in C++23.

When libc++'s stdatomic.h is included in C translation units, delegate
to the next stdatomic.h, which could come from Clang or libc.
---
 libcxx/include/atomic                         |  4 ----
 libcxx/include/stdatomic.h                    | 14 +++++------
 ...compatible_with_stdatomic.compile.pass.cpp | 22 ++++++++++++++++++
 .../incompatible_with_stdatomic.verify.cpp    | 22 ------------------
 .../dont_hijack_header.compile.pass.cpp       | 23 -------------------
 5 files changed, 29 insertions(+), 56 deletions(-)
 create mode 100644 libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
 delete mode 100644 libcxx/test/libcxx/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
 delete mode 100644 libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.compile.pass.cpp

diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index 80a0f9ee373e9..183e8a0d2d2cd 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -589,10 +589,6 @@ template <class T>
 
 #include <__config>
 
-#if _LIBCPP_STD_VER < 23 && defined(_LIBCPP_STDATOMIC_H)
-#  error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
-#endif
-
 #include <__atomic/aliases.h>
 #include <__atomic/atomic.h>
 #include <__atomic/atomic_base.h>
diff --git a/libcxx/include/stdatomic.h b/libcxx/include/stdatomic.h
index 79772eb7fce1f..34fe75536736f 100644
--- a/libcxx/include/stdatomic.h
+++ b/libcxx/include/stdatomic.h
@@ -121,7 +121,7 @@ using std::atomic_signal_fence                         // see below
 #  pragma GCC system_header
 #endif
 
-#if defined(__cplusplus) && _LIBCPP_STD_VER >= 23
+#if defined(__cplusplus)
 
 #  include <atomic>
 #  include <version>
@@ -154,10 +154,14 @@ using std::atomic_long _LIBCPP_USING_IF_EXISTS;
 using std::atomic_ulong _LIBCPP_USING_IF_EXISTS;
 using std::atomic_llong _LIBCPP_USING_IF_EXISTS;
 using std::atomic_ullong _LIBCPP_USING_IF_EXISTS;
+#  ifndef _LIBCPP_HAS_NO_CHAR8_T
 using std::atomic_char8_t _LIBCPP_USING_IF_EXISTS;
+#  endif
 using std::atomic_char16_t _LIBCPP_USING_IF_EXISTS;
 using std::atomic_char32_t _LIBCPP_USING_IF_EXISTS;
+#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 using std::atomic_wchar_t _LIBCPP_USING_IF_EXISTS;
+#  endif
 
 using std::atomic_int8_t _LIBCPP_USING_IF_EXISTS;
 using std::atomic_uint8_t _LIBCPP_USING_IF_EXISTS;
@@ -220,16 +224,12 @@ using std::atomic_store_explicit _LIBCPP_USING_IF_EXISTS;
 using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS;
 using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS;
 
-#elif defined(_LIBCPP_COMPILER_CLANG_BASED)
+#else
 
-// Before C++23, we include the next <stdatomic.h> on the path to avoid hijacking
-// the header. We do this because Clang has historically shipped a <stdatomic.h>
-// header that would be available in all Standard modes, and we don't want to
-// break that use case.
 #  if __has_include_next(<stdatomic.h>)
 #    include_next <stdatomic.h>
 #  endif
 
-#endif // defined(__cplusplus) && _LIBCPP_STD_VER >= 23
+#endif // defined(__cplusplus)
 
 #endif // _LIBCPP_STDATOMIC_H
diff --git a/libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp b/libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
new file mode 100644
index 0000000000000..210bb333ad715
--- /dev/null
+++ b/libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-threads
+
+// This test verifies that <stdatomic.h> redirects to <atomic>. As an extension,
+// libc++ enables this redirection even before C++23.
+
+// Ordinarily, <stdatomic.h> can be included after <atomic>, but including it
+// first doesn't work because its macros break <atomic>. Verify that
+// <stdatomic.h> can be included first.
+#include <stdatomic.h>
+#include <atomic>
+
+#include <type_traits>
+
+static_assert(std::is_same<atomic_int, std::atomic<int>>::value, "");
diff --git a/libcxx/test/libcxx/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp b/libcxx/test/libcxx/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
deleted file mode 100644
index ca092d9c60275..0000000000000
--- a/libcxx/test/libcxx/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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-threads
-// REQUIRES: c++03 || c++11 || c++14 || c++17 || c++20
-
-// This test ensures that we issue a reasonable diagnostic when including <atomic> after
-// <stdatomic.h> has been included. Before C++23, this otherwise leads to obscure errors
-// because <atomic> may try to redefine things defined by <stdatomic.h>.
-
-// Ignore additional weird errors that happen when the two headers are mixed.
-// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error -Xclang -verify-ignore-unexpected=warning
-
-#include <stdatomic.h>
-#include <atomic>
-
-// expected-error@*:* {{<atomic> is incompatible with <stdatomic.h> before C++23.}}
diff --git a/libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.compile.pass.cpp b/libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.compile.pass.cpp
deleted file mode 100644
index f35eddfb35335..0000000000000
--- a/libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.compile.pass.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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-threads
-
-// This test ensures that we don't hijack the <stdatomic.h> header even when compiling
-// before C++23, since Clang used to provide that header before libc++ provided one.
-
-// On GCC, the compiler-provided <stdatomic.h> is not C++ friendly, so including <stdatomic.h>
-// doesn't work at all if we don't use the <stdatomic.h> provided by libc++ in C++23 and above.
-// XFAIL: (c++11 || c++14 || c++17 || c++20) && gcc
-
-#include <stdatomic.h>
-
-void f() {
-  atomic_int i; // just make sure the header isn't empty
-  (void)i;
-}

>From 7b24c13786113ef40e69a39febfaa70505534e2b Mon Sep 17 00:00:00 2001
From: Ryan Prichard <rprichard at google.com>
Date: Fri, 14 Jun 2024 19:45:28 -0700
Subject: [PATCH 2/2] Add a space between >> so generic-cxx03 test passes

---
 .../atomics.syn/compatible_with_stdatomic.compile.pass.cpp      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp b/libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
index 210bb333ad715..a52459abb9e0a 100644
--- a/libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
+++ b/libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
@@ -19,4 +19,4 @@
 
 #include <type_traits>
 
-static_assert(std::is_same<atomic_int, std::atomic<int>>::value, "");
+static_assert(std::is_same<atomic_int, std::atomic<int> >::value, "");



More information about the libcxx-commits mailing list