Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions libcxx/include/atomic
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,16 @@ template <class T>
#else
# include <__config>

# if defined(_LIBCPP_STDATOMIC_H) || defined(kill_dependency) || defined(atomic_load)
# define _LIBCPP_STDATOMIC_H_HAS_DEFINITELY_BEEN_INCLUDED 1
# else
# define _LIBCPP_STDATOMIC_H_HAS_DEFINITELY_BEEN_INCLUDED 0
# endif

# if _LIBCPP_STD_VER < 23 && _LIBCPP_STDATOMIC_H_HAS_DEFINITELY_BEEN_INCLUDED
# 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_flag.h>
Expand Down
10 changes: 7 additions & 3 deletions libcxx/include/stdatomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ using std::atomic_signal_fence // see below
# pragma GCC system_header
# endif

# if defined(__cplusplus)
# if defined(__cplusplus) && _LIBCPP_STD_VER >= 23

# include <atomic>
# include <version>
Expand Down Expand Up @@ -231,13 +231,17 @@ 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;

# else
# elif defined(_LIBCPP_COMPILER_CLANG_BASED)

// 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)
# endif // defined(__cplusplus) && _LIBCPP_STD_VER >= 23
#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_STDATOMIC_H
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: no-threads
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// XFAIL: FROZEN-CXX03-HEADERS-FIXME

// This test verifies that <stdatomic.h> redirects to <atomic>. As an extension,
// libc++ enables this redirection even before C++23.
// This test verifies that <stdatomic.h> redirects to <atomic>.

// 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.
// Before C++23, <stdatomic.h> can be included after <atomic>, but including it
// first doesn't work because its macros break <atomic>. Fixing that is the point
// of the C++23 change that added <stdatomic.h> to C++. Thus, this test verifies
// that <stdatomic.h> can be included first.
#include <stdatomic.h>
#include <atomic>

Expand Down
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
// 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.}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// 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 (e.g. by providing
// an empty header) even when compiling before C++23, since some users were using the
// Clang or platform provided header before libc++ added its own.

// 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;
}
Original file line number Diff line number Diff line change
@@ -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-threads

// This test verifies that <stdatomic.h> DOES NOT redirect to <atomic> before C++23,
// since doing so is a breaking change. Several things can break when that happens,
// because the type of _Atomic(T) changes from _Atomic(T) to std::atomic<T>.
//
// For example, redeclarations can become invalid depending on whether they
// have been declared with <stdatomic.h> in scope or not.

// REQUIRES: c++03 || c++11 || c++14 || c++17 || c++20

// 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 <atomic>
#include <stdatomic.h>
#include <type_traits>

static_assert(!std::is_same<_Atomic(int), std::atomic<int> >::value, "");
Loading