-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
[libc++] Enable C++ stdatomic.h for all C++ versions #95498
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this header from libc++ is supposed to only be included in C++ mode, we should always take this branch and the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Many of the libc++ C headers also have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nevermind, I was under the wrong impression that |
||
|
||
# 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The using-if-exists attribute should handle this, is there a reason why you're adding this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like GCC doesn't have the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right. |
||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, ""); |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we claim that
<atomic>
is incompatible with<stdatomic.h>
before C++23? Can you refresh my memory? In other words, what changed in C++23 that made the header compatible?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++ versions before C++23 don't specify a
<stdatomic.h>
, so including<stdatomic.h>
in a C++ file typically finds<stdatomic.h
> from the C library (or maybe from Clang's resource directory). That header typically implements<stdatomic.h>
from C11, which typically implements type-generic operations using macros. For example,atomic_is_lock_free
is a macro that works with any_Atomic
-qualified object:From clang/lib/Headers/stdatomic.h:
If
<stdatomic.h>
is included first, then this macro will break the parsing ofstd::atomic_is_lock_free
when<atomic>
is included later (e.g. libcxx/include/__atomic/atomic.h):It can be possible to use the C11
<stdatomic.h>
in a C++ file, as long as<atomic>
is included first (or not at all), and only if the C++ compiler and<stdatomic.h>
are compatible. For example:<stdatomic.h>
in C++ mode because GCC only provides the_Atomic
qualifier in C mode, not C++.<stdatomic.h>
in C++ mode.Other STL headers that use the C11
<stdatomic.h>
identifiers can also be an issue. For example, including<memory>
after<stdatomic.h>
also hits the incompatibility:Including
<memory>
definesstd::atomic_*
function overloads forstd::shared_ptr
(until C++26, when they are removed). https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic