Skip to content

[libc++][Android] Always redirect <stdatomic.h> to <atomic> #143036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rprichard
Copy link
Contributor

When targeting Android, enable the <stdatomic.h> to redirection for C++ language dialects before C++23, because this redirection historically existed for Android's C++ toolchain. Currently, the Android toolchain achieves this redirection with a stdatomic.h in the sysroot (from Bionic) that defines the C API either directly or by aliasing std identifiers from . The Android team's LLVM build scripts then copy Bionic's header over the one in the Clang resource directory.

Hopefully, by moving Android's redirection into LLVM itself, the Android stdatomic.h situation can be simplified eventually.

When targeting Android, enable the <stdatomic.h> to <atomic>
redirection for C++ language dialects before C++23, because this
redirection historically existed for Android's C++ toolchain.
Currently, the Android toolchain achieves this redirection with a
stdatomic.h in the sysroot (from Bionic) that defines the C API either
directly or by aliasing std identifiers from <atomic>. The Android
team's LLVM build scripts then copy Bionic's header over the one in the
Clang resource directory.

Hopefully, by moving Android's redirection into LLVM itself, the
Android stdatomic.h situation can be simplified eventually.
@rprichard rprichard requested a review from a team as a code owner June 5, 2025 21:19
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jun 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-libcxx

Author: Ryan Prichard (rprichard)

Changes

When targeting Android, enable the <stdatomic.h> to <atomic> redirection for C++ language dialects before C++23, because this redirection historically existed for Android's C++ toolchain. Currently, the Android toolchain achieves this redirection with a stdatomic.h in the sysroot (from Bionic) that defines the C API either directly or by aliasing std identifiers from <atomic>. The Android team's LLVM build scripts then copy Bionic's header over the one in the Clang resource directory.

Hopefully, by moving Android's redirection into LLVM itself, the Android stdatomic.h situation can be simplified eventually.


Full diff: https://github.com/llvm/llvm-project/pull/143036.diff

5 Files Affected:

  • (modified) libcxx/include/atomic (+4-1)
  • (modified) libcxx/include/stdatomic.h (+4-1)
  • (modified) libcxx/test/libcxx/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp (+4-1)
  • (modified) libcxx/test/libcxx/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp (+3)
  • (modified) libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp (+3)
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index 75af5de33ca4c..fba7040f6900c 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -598,7 +598,10 @@ template <class T>
 #    define _LIBCPP_STDATOMIC_H_HAS_DEFINITELY_BEEN_INCLUDED 0
 #  endif
 
-#  if _LIBCPP_STD_VER < 23 && _LIBCPP_STDATOMIC_H_HAS_DEFINITELY_BEEN_INCLUDED
+// The Android LLVM toolchain has historically allowed combining the <atomic>
+// and <stdatomic.h> headers in dialects before C++23, so for backwards
+// compatibility, preserve that ability when targeting Android.
+#  if _LIBCPP_STD_VER < 23 && !defined(__ANDROID__) && _LIBCPP_STDATOMIC_H_HAS_DEFINITELY_BEEN_INCLUDED
 #    error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
 #  endif
 
diff --git a/libcxx/include/stdatomic.h b/libcxx/include/stdatomic.h
index 2991030eee456..dc1a955b69cb6 100644
--- a/libcxx/include/stdatomic.h
+++ b/libcxx/include/stdatomic.h
@@ -126,7 +126,10 @@ using std::atomic_signal_fence                         // see below
 #    pragma GCC system_header
 #  endif
 
-#  if defined(__cplusplus) && _LIBCPP_STD_VER >= 23
+// The Android LLVM toolchain has historically allowed combining the <atomic>
+// and <stdatomic.h> headers in dialects before C++23, so for backwards
+// compatibility, preserve that ability when targeting Android.
+#  if defined(__cplusplus) && (_LIBCPP_STD_VER >= 23 || defined(__ANDROID__))
 
 #    include <atomic>
 #    include <version>
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 349dc51aaa0e6..c997e4b792459 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
@@ -7,7 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: no-threads
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// On Android, libc++'s <stdatomic.h> header always redirects to <atomic>, even before C++23.
+// UNSUPPORTED: c++03
+// UNSUPPORTED: (c++11 || c++14 || c++17 || c++20) && !android
 
 // This test verifies that <stdatomic.h> redirects to <atomic>.
 
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
index a788ea32dddc8..7d14fa308bf06 100644
--- a/libcxx/test/libcxx/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
+++ b/libcxx/test/libcxx/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
@@ -9,6 +9,9 @@
 // UNSUPPORTED: no-threads
 // REQUIRES: c++03 || c++11 || c++14 || c++17 || c++20
 
+// On Android, libc++'s <stdatomic.h> header always redirects to <atomic>, even before C++23.
+// XFAIL: android
+
 // No diagnostic gets emitted when we build with modules.
 // XFAIL: clang-modules-build
 
diff --git a/libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp b/libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp
index a8a99e6937f31..5c966c6bca6e2 100644
--- a/libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp
+++ b/libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp
@@ -21,6 +21,9 @@
 // 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
 
+// On Android, libc++'s <stdatomic.h> header always redirects to <atomic>, even before C++23.
+// XFAIL: android
+
 #include <atomic>
 #include <stdatomic.h>
 #include <type_traits>

@rprichard
Copy link
Contributor Author

Some more context:

I'm trying to make the Android situation less clumsy, by making the upstream LLVM headers acceptable to use as-is, for the Android toolchain team's build of LLVM.

I think our team would actually prefer a way to enable the backport even when we target non-Android, but I don't know if this desire warrants adding a config flag (e.g. to __config_site).

I'm wondering if upstream libc++ has any thoughts on restoring the backport, but only when targeting Android.

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// On Android, libc++'s <stdatomic.h> header always redirects to <atomic>, even before C++23.
// UNSUPPORTED: c++03
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is c++03 on a separate line now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably shouldn't be on a separate line -- it looks like libc++ does support <atomic> for C++03.

Though now I'm wondering if the UNSUPPORTED directive ought to be XFAIL instead. I think the libc++ project usually prefers XFAIL when we know that a test should fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose UNSUPPORTED might be fine, though, because for previous language dialects, we have the incompatible_with_stdatomic.verify.cpp test already.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd move back c++03 on the same line as the other ones. I'm neutral on XFAIL vs UNSUPPORTED -- as you mention we already have a dedicated test for the inverse behavior.

Copy link
Contributor

@enh-google enh-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(the config option so we can have this for Android host builds too sounds even better, but at least this lets us not hurt app developers and keep any pain "just" to OS developers...)

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do have a bit of a concern with making this part of upstream: that makes libc++ non-conforming in pre-C++23 modes (in particular, libcxx/test/libcxx/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp doesn't pass).

Have you folks looked into removing that historical extension on the Android side? If that's something Android would be open to, I could suggest the following:

  • We take this patch and upstream your support, but we also add a deprecation warning and a release note that this will be dropped in the future
  • In 1-2 releases (there's flexibility here), we remove the extension, while optionally providing an escape hatch to bring it back.
  • After one more release, we remove the escape hatch.

That solution:

  • Gives plenty of time for Android users to migrate / fix their code (between 1 year and 1.5 years)
  • Allows Android to upstream this diff
  • Allows libc++ to eventually drop this debt and ensure conformance on all platforms, like we aim to

Would something like this be reasonable from Android's side?

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// On Android, libc++'s <stdatomic.h> header always redirects to <atomic>, even before C++23.
// UNSUPPORTED: c++03
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd move back c++03 on the same line as the other ones. I'm neutral on XFAIL vs UNSUPPORTED -- as you mention we already have a dedicated test for the inverse behavior.

@enh-google
Copy link
Contributor

Have you folks looked into removing that historical extension on the Android side? If that's something Android would be open to, I could suggest the following:

our problem is (as you guessed) that this is exposed to app developers and partners (both SoC vendors and device manufacturers). we've tried things like you suggest in the past, and the trouble is that people fall into one of two groups: the -Werror group (who you've now broken) and the "ain't nobody got time for warnings" group (who won't do anything until/unless you break them).

given that there's no advantage to breaking anyone, it's hard to justify this.

(don't get me started on the transitive include "cleanup" in c++23 ... that's going to have everyone mad at me :-( )

for /<stdatomic.h> is there a way we can move the hackery out into our header which does an #include_next?

Gives plenty of time for Android users to migrate / fix their code (between 1 year and 1.5 years)

(ah, the joys of working for apple :-) )

@pirama-arumuga-nainar
Copy link
Collaborator

Have you folks looked into removing that historical extension on the Android side? If that's something Android would be open to, I could suggest the following:

As a historic note, P0943 stemmed from our attempt to standardize the Android-specific extension.

I agree with enh about not breaking our users. Moreover, spending effort to fix Android codebase for the pre-C++-23 mode, while it is expected to work in C++23 and later, doesn't seem like a valuable use of resources. Upgrading to C++23 is the viable strategy here. We can foresee updating Android platform (and vendors) to C++-23 in the next 1-2 years, but breaking app developers is something we want to avoid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants