https://github.com/llvm/llvm-project/pull/95498 implemented a libc++
extension where <stdatomic.h> would forward to <atomic> even before
C++23. Unfortunately, this was found to be a breaking change (with
fairly widespread impact) since that changes whether _Atomic(T) is a C
style atomic or std::atomic<T>. In principle, this can even be an ABI
break.
We generally don't implement extensions in libc++ because they cause so
many problems, and that extension had been accepted because it was
deemed pretty small and only a quality of life improvement. Since it has
widespread impact on valid C++20 (and before) code, this patch removes
the extension before we ship it in any public release.
This patch implements the forwarding to frozen C++03 headers as
discussed in
https://discourse.llvm.org/t/rfc-freezing-c-03-headers-in-libc. In the
RFC, we initially proposed selecting the right headers from the Clang
driver, however consensus seemed to steer towards handling this in the
library itself. This patch implements that direction.
At a high level, the changes basically amount to making each public
header look like this:
```
// inside <vector>
#ifdef _LIBCPP_CXX03_LANG
# include <__cxx03/vector>
#else
// normal <vector> content
#endif
```
In most cases, public headers are simple umbrella headers so there isn't
much code in the #else branch. In other cases, the #else branch contains
the actual implementation of the header.
This patch documents the underlying API for implementing atomics on a
platform.
This doesn't change the operations that std::atomic is based on, but it
reorganizes the C11 / GCC implementation split to make it clearer what's
the base support layer and what's not.
The __atomic_base base class is only useful to conditionalize the
operations we provide inside std::atomic. It shouldn't be used directly
from other places in the library which can use std::atomic directly
instead.
Since we've granularized our includes, using std::atomic directly should
not make much of a difference compile-time wise.
This patch starts using std::atomic directly from other classes like
std::barrier and std::latch. Changing this shouldn't be an ABI break
since both classes have the same size and layout.
The benefits of this patch are isolating other parts of the code base
from implementation details of std::atomic and simplifying the mental
model for std::atomic's layers of implementation by making it clear that
__atomic_base is only an implementation detail of std::atomic.
Currently, the library-internal feature test macros are only defined if
the feature is not available, and always have the prefix
`_LIBCPP_HAS_NO_`. This patch changes that, so that they are always
defined and have the prefix `_LIBCPP_HAS_` instead. This changes the
canonical use of these macros to `#if _LIBCPP_HAS_FEATURE`, which means
that using an undefined macro (e.g. due to a missing include) is
diagnosed now. While this is rather unlikely currently, a similar change
in `<__configuration/availability.h>` caught a few bugs. This also
improves readability, since it removes the double-negation of `#ifndef
_LIBCPP_HAS_NO_FEATURE`.
The current patch only touches the macros defined in `<__config>`. If
people are happy with this approach, I'll make a follow-up PR to also
change the macros defined in `<__config_site>`.
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.
When we initially implemented the C++20 synchronization library, we
reluctantly accepted for the implementation to be backported to C++03
upon request from the person who provided the patch. This was when we
were only starting to have experience with the issues this can create,
so we flinched. Nowadays, we have a much stricter stance about not
backporting features to previous standards.
We have recently started fixing several bugs (and near bugs) in our
implementation of the synchronization library. A recurring theme during
these reviews has been how difficult to understand the current code is,
and upon inspection it becomes clear that being able to use a few recent
C++ features (in particular lambdas) would help a great deal. The code
would still be pretty intricate, but it would be a lot easier to reason
about the flow of callbacks through things like
__thread_poll_with_backoff.
As a result, this patch drops support for the synchronization library
before C++20. This makes us more strictly conforming and opens the door
to major simplifications, in particular around atomic_wait which was
supported all the way to C++03.
This change will probably have some impact on downstream users, however
since the C++20 synchronization library was added only in LLVM 10 (~3
years ago) and it's quite a niche feature, the set of people trying to
use this part of the library before C++20 should be reasonably small.
We normally try to issue a reasonable diagnostic when mixing
<stdatomic.h> and <atomic> before C++23. However, after granularizing
the <atomic> header, the check and the #error message was moved to
*after* the point where mixing both causes problems. When mixing both
headers, we would hence get the diagnostic burried under a pile of
previous diagnostics in e.g. __atomic/kill_dependency.h.
This patch moves the check earlier to restore the intended behavior. It
also switches from `#ifdef kill_dependency` to an explicit check of the
inclusion of the header and the Standard version, which seems to be more
reliable than checking whether a macro is defined.
Originally, we used __libcpp_verbose_abort to handle assertion failures.
That function was declared from all public headers. Since we don't use
that mechanism anymore, we don't need to declare __libcpp_verbose_abort
from all public headers, and we can clean up a lot of unnecessary
includes.
This patch also moves the definition of the various assertion categories
to the <__assert> header, since we now rely on regular IWYU for these
assertion macros.
rdar://105510916
Their definition was a bit roundabout and it was actually wrong since
atomic_unsigned_lock_free would be a signed type whenever
__cxx_contention_t is lock free, which is most of the time.
Fixes#72968
This change is almost fully mechanical. The only interesting change is in `generate_feature_test_macro_components.py` to generate `_LIBCPP_STD_VER >=` instead. To avoid churn in the git-blame this commit should be added to the `.git-blame-ignore-revs` once committed.
Reviewed By: ldionne, var-const, #libc
Spies: jloser, libcxx-commits, arichardson, arphaman, wenlei
Differential Revision: https://reviews.llvm.org/D143962
Some of the calendar types have landed before, this adds the missing
set. Note this does not complete the implementation of the chrono
formatters.
This removes the `chrono` header for some transitive include in C++17
mode. This is needed to avoid inclusion cycles.
Partially implements:
- P1361 Integration of chrono with text formatting
- P2372 Fixing locale handling in chrono formatters
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D137022
The noexcept was already implemented, this only updates the synposis and
adds tests to validate that the functions are noexcept.
This implements:
- LWG3745 std::atomic_wait and its friends lack noexcept
Reviewed By: #libc, philnik
Differential Revision: https://reviews.llvm.org/D140575
The new version is a lot simpler and has less option which were not
used. This uses the CSV files as generated by D133127 as input data.
The current Python script has more features but uses a simple "grep"
making the output less accurate:
- Conditionally included header are always included. This is an issue
since part of our includes are unneeded transitive includes. Based on
the language version they may be omitted. The script however always
includes them.
- Includes in comments are processed as-if they are includes. This is an
issue when comments explain how certain data is generated; of course
there are digraphs which the script omits.
This implementation uses Clang's --trace-includes to generate the includes
per header. This means the input of the generation script always has the
real list of includes.
Libc++ is moving from large monolithic Standard headers to more fine
grained headers. For example, algorithm includes every header in
`__algorithm`. Adding all these detail headers in the graph makes the
output unusable. Instead it only shows the Standard headers. The
transitive includes of the detail headers are parsed and "attributed" to
the Standard header including them. This gives an accurate include graph
without the unneeded clutter. Note that this graph is still big.
This changes fixes the cyclic dependency issue with the previous version
of the tool so the markers and its documentation is removed.
Since the input has no cycles the CI test is removed.
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D134188
In https://llvm.org/D56913, we added an emulation for the __atomic_always_lock_free
compiler builtin when compiling in Freestanding mode. However, the emulation
did (and could not) give exactly the same answer as the compiler builtin,
which led to a potential ABI break for e.g. enum classes.
After speaking to the original author of D56913, we agree that the correct
behavior is to instead always use the compiler builtin, since that provides
a more accurate answer, and __atomic_always_lock_free is a purely front-end
builtin which doesn't require any runtime support. Furthermore, it is
available regardless of the Standard mode (see https://godbolt.org/z/cazf3ssYY).
However, this patch does constitute an ABI break. As shown by https://godbolt.org/z/1eoex6zdK:
- In LLVM <= 11.0.1, an atomic<enum class with 1 byte> would not contain a lock byte.
- In LLVM >= 12.0.0, an atomic<enum class with 1 byte> would contain a lock byte.
This patch breaks the ABI again to bring it back to 1 byte, which seems
like the correct thing to do.
Fixes#57440
Differential Revision: https://reviews.llvm.org/D133377
As the comment suggests, `_LIBCPP_HAS_NO_PLATFORM_WAIT` is not documented or
defined anywhere internally in the build system. It's a direct define in terms
of `_LIBCPP_HAS_NO_THREADS`. So, remove `_LIBCPP_HAS_NO_PLATFORM_WAIT` and use
`_LIBCPP_HAS_NO_THREADS` instead to control the desired behavior.
Differential Revision: https://reviews.llvm.org/D132715
This defines a new policy for removal of transitive includes.
The goal of the policy it to make it relatively easy to remove
headers when needed, but avoid breaking developers using and
vendors shipping libc++.
The method used is to guard transitive includes based on the
C++ language version. For the upcoming C++23 we can remove
headers when we want, but for other language versions we try
to keep it to a minimum.
In this code the transitive include of `<chrono>` is removed
since D128577 introduces a header cycle between `<format>`
and `<chrono>`. This cycle is indirectly required by the
Standard. Our cycle dependency tool basically is a grep based
tool, so it needs some hints to ignore cycles. With the input
of our transitive include tests we can create a better tool.
However that's out of the scope of this patch.
Note the flag `_LIBCPP_REMOVE_TRANSITIVE_INCLUDES` remains
unchanged. So users can still opt-out of transitives includes
entirely.
Reviewed By: #libc, ldionne, philnik
Differential Revision: https://reviews.llvm.org/D132284
This was discussed on Discord with the consensus that we should rename the macros.
Reviewed By: ldionne, Mordante, var-const, avogelsgesang, jloser, #libc
Spies: libcxx-commits
Differential Revision: https://reviews.llvm.org/D131498
According to @aaron.ballman this was marked Tentatively Ready as of 2022-07-07.
D129362 implemented the C counterpart.
Reviewed By: ldionne, #libc, Mordante
Differential Revision: https://reviews.llvm.org/D129380
This commit re-adds transitive includes that had been removed by
4cd04d1687f1, c36870c8e79c, a83f4b9cda57, 1458458b558d, 2e2f3158c604,
and 489637e66dd3. This should cover almost all the includes that had
been removed since LLVM 14 and that would contribute to breaking user
code when releasing LLVM 15.
It is possible to disable the inclusion of these headers by defining
_LIBCPP_REMOVE_TRANSITIVE_INCLUDES. The intent is that vendors will
enable that macro and start fixing downstream issues immediately. We
can then remove the macro (and the transitive includes) by default in
a future release. That way, we will break users only once by removing
transitive includes in bulk instead of doing it bit by bit a every
release, which is more disruptive for users.
Note 1: The set of headers to re-add was found by re-generating the
transitive include test on a checkout of release/14.x, which
provided the list of all transitive includes we used to provide.
Note 2: Several includes of <vector>, <optional>, <array> and <unordered_map>
have been added in this commit. These transitive inclusions were
added when we implemented boyer_moore_searcher in <functional>.
Note 3: This is a best effort patch to try and resolve downstream breakage
caused since branching LLVM 14. I wasn't able to perfectly mirror
transitive includes in LLVM 14 for a few headers, so I added a
release note explaining it. To summarize, adding boyer_moore_searcher
created a bunch of circular dependencies, so we have to break
backwards compatibility in a few cases.
Differential Revision: https://reviews.llvm.org/D128661
I guess this is an ABI break for the 32 bit AIX configuration, but I'm
not sure if that one is meant to be ABI stable yet or not.
Previously, this used int32_t for this type on linux, but int64_t
on all other platforms. This was added in D68480 /
54fa9ecd3088508b05b0c5b5cb52da8a3c188655, but I don't really see
any discussion around this detail there.
Switching this to 32 bit on 32 bit AIX silences these libcxx build
warnings:
```
In file included from /scratch/powerllvm/cpap8006/llvm-project/libcxx-ci/libcxx/src/atomic.cpp:12:
/scratch/powerllvm/cpap8006/llvm-project/libcxx-ci/build/aix/include/c++/v1/atomic:1005:12: warning: large atomic operation may incur significant performance penalty; the access size (8 bytes) exceeds the max lock-free size (4 bytes) [-Watomic-alignment]
return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
^
/scratch/powerllvm/cpap8006/llvm-project/libcxx-ci/build/aix/include/c++/v1/atomic:948:12: warning: large atomic operation may incur significant performance penalty; the access size (8 bytes) exceeds the max lock-free size (4 bytes) [-Watomic-alignment]
return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
^
/scratch/powerllvm/cpap8006/llvm-project/libcxx-ci/build/aix/include/c++/v1/atomic:1000:12: warning: large atomic operation may incur significant performance penalty; the access size (8 bytes) exceeds the max lock-free size (4 bytes) [-Watomic-alignment]
return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
^
/scratch/powerllvm/cpap8006/llvm-project/libcxx-ci/build/aix/include/c++/v1/atomic:1022:12: warning: large atomic operation may incur significant performance penalty; the access size (8 bytes) exceeds the max lock-free size (4 bytes) [-Watomic-alignment]
return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
^
4 warnings generated.
```
Differential Revision: https://reviews.llvm.org/D124519
This patch changes the requirement for getting the declaration of the
assertion handler from including <__assert> to including any public
C++ header of the library. Note that C compatibility headers are
excluded because we don't implement all the C headers ourselves --
some of them are taken straight from the C library, like assert.h.
It also adds a generated test to check it. Furthermore, this new
generated test is designed in a way that will make it possible to
replace almost all the existing test-generation scripts with this
system in upcoming patches.
Differential Revision: https://reviews.llvm.org/D122506
This reverts commits a30a7948d and 5d1c1a243, which broke the LLDB
data formatters tests because they build with modules in C++11 mode.
Differential Revision: https://reviews.llvm.org/D97044
On targets that have limited atomic support, e.g. ones that define
ATOMIC_*_LOCK_FREE to '1' ("sometimes lock free"), we would end up
referencing yet-undefined __libcpp_{,un}signed_lock_free.
This commit adds a guard to prevent these references for such
targets.
Differential Revision: https://reviews.llvm.org/D118391
This change is the basis for a further refactoring where I'm going to
split up the various implementations we have in __threading_support to
make that code easier to understand.
Note that I had to make __convert_to_timespec a template to break
circular dependencies. Concretely, we never seem to use it with anything
other than ::timespec, but I am wary of hardcoding that assumption as
part of this change, since I suspect there's a reason for going through
these hoops in the first place.
Differential Revision: https://reviews.llvm.org/D116944
When P0883R2 was initially implemented in D103769 #pragma clang deprecated didn't exist yet.
We also forgot to cleanup usages in libc++ itself.
This takes care of both.
Differential Revision: https://reviews.llvm.org/D115995
clang has `= default` as an extension in c++03, so just use it.
Reviewed By: ldionne, Quuxplusone, #libc
Spies: libcxx-commits
Differential Revision: https://reviews.llvm.org/D115275
std::atomic is, for the most part, just a thin veneer on top of compiler
builtins. Hence, it should be available even when threads are not available
on the system, and in fact there has been requests for such support.
This patch:
- Moves __libcpp_thread_poll_with_backoff to its own header so it can
be used in <atomic> when threads are disabled.
- Adds a dummy backoff policy for atomic polling that doesn't know about
threads.
- Adjusts the <atomic> feature-test macros so they are provided even when
threads are disabled.
- Runs the <atomic> tests when threads are disabled.
rdar://77873569
Differential Revision: https://reviews.llvm.org/D114109
We've stopped doing it in libc++ for a while now because these names
would end up rotting as we move things around and copy/paste stuff.
This cleans up all the existing files so as to stop the spreading
as people copy-paste headers around.
- Replace irrelevant synopsis by a comment
- Use a .verify.cpp test instead of .compile.fail.cpp
- Remove unnecessary includes in one of the tests (was a copy-paste error)
Differential Revision: https://reviews.llvm.org/D114094
While looking at LWG-2988 and P0558 it seems the issues were already
implemented, but the synopsis wasn't updated. Some of the tests didn't
validate the `noexcept` status. A few tests were missing completely:
- `atomic_wait_explicit`
- `atomic_notify_one`
- `atomic_notify_all`
Mark P0558 as complete, didn't investigate which version of libc++ first
includes this. It seems the paper has been retroactively applied. I
couldn't find whether this is correct, but looking at cppreference it
seems intended.
Completes
- LWG-2988 Clause 32 cleanup missed one typename
- P0558 Resolving atomic<T> named base class inconsistencies
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D103765