Commit Graph

501 Commits

Author SHA1 Message Date
A. Jiang
63eb40eeb1 [libc++] Deprecate and remove meaningless <cxxx> headers (#111615)
This PR deprecates `<ccomplex>`, `<cstdbool>`, `<ctgmath>`, and
`<ciso646>` in C++17 and "removes" them in C++20 by special deprecation
warnings.

`<cstdalign>` is previously missing. This PR also tries to add them, and
then deprecates and "removes" `<cstdalign>`.

Papers:
- https://wg21.link/P0063R3
- https://wg21.link/P0619R4

Closes #99985.

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2024-10-30 09:49:26 +08:00
A. Jiang
cae351f345 [libc++] Bump __cpp_lib_optional and __cpp_lib_variant (#113650)
In C++20 mode, `__cpp_lib_optional` and `__cpp_lib_variant` should be
`202106L` due to DR P2231R1.

In C++26 mode, `__cpp_lib_variant` should be bumped to `202306L` due to
P2637R3.
- Clang 16/17 shouldn't get this bumping (as member `visit` requires
explicit object parameters), but it's very tricky to make the bumping
conditionally enabled. I _hope_ unconditionally bumping in C++26 will be
OK for LLVM 20 when the support for Clang 17 is dropped.

Related PRs:
- https://reviews.llvm.org/D102119
- #83335
- #76447
2024-10-26 07:38:52 +08:00
Hristo Hristov
a06591b4d4 [libc++][type_traits] P2674R1: A trait for implicit lifetime types (#106870)
Implements P2674R1: https://wg21.link/P2674R1

- https://eel.is/c++draft/type.traits
  - https://eel.is/c++draft/meta.type.synop
  - https://eel.is/c++draft/meta.unary.prop
- https://eel.is/c++draft/support.limits
  - https://eel.is/c++draft/version.syn

Implementation details:
- Uses compiler intrinsic `__builtin_is_implicit_lifetime`:
  - https://github.com/llvm/llvm-project/pull/101807
- Tests based on:
-
d213981c80/clang/test/SemaCXX/type-traits.cpp (L1989)

References:
- Implicit-lifetime
- Implicit-lifetime types [basic.types.general]/9:
https://eel.is/c++draft/basic.types.general
- Implicit-lifetime class [class.prop]/9:
https://eel.is/c++draft/class.prop
- P0593R6 Implicit creation of objects for low-level object
manipulation: https://wg21.link/P0593R6
- P1010R1 Container support for implicit lifetime types:
https://wg21.link/P1010R1
- P0593R6 Implicit creation of objects for low-level object
manipulation: https://wg21.link/P0593R6

Closes: #105259

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
2024-10-09 08:19:14 +02:00
A. Jiang
557f7e1398 [libc++] P2167R3: Improved Proposed Wording for LWG 2114 (#109102)
Only the [cmp.alg] part (for `comparison_meow_fallback` CPOs) in the
paper required changes. Other parts merely fixed preconditions of some
standard library functions.

I strongly feel that P2167R3 should be a DR despite that it is not a DR
officially: CPOs -> C++20; remain parts -> C++98/11 (except that
_`boolean-testable`_ should be transformed into the original
_BooleanTestable_ requirements in the old resolution of LWG2114).

Note that P2167R3 damaged the resolution of LWG3465: the type of `F < E`
was left underconstrained. I've tried to submit an LWG issue for this,
which is now LWG4157.

Drive-by change:
- enable some test coverages in `compare_strong_order_fallback.pass.cpp`
when `TEST_LONG_DOUBLE_IS_DOUBLE`, following up #106742

Closes #105241.
2024-10-03 01:09:53 +08:00
Louis Dionne
09e3a36058 [libc++][modules] Fix missing and incorrect includes (#108850)
This patch adds a large number of missing includes in the libc++ headers
and the test suite. Those were found as part of the effort to move
towards a mostly monolithic top-level std module.
2024-09-16 15:06:20 -04:00
Louis Dionne
99174842ae [libc++] Make std::jthread supported in non-experimental mode (#107900)
We waited before supporting std::jthread fully because we wanted to
investigate other implementation strategies (in particular one involving
std::mutex). Since then, we did some benchmarking and decided that we
wouldn't be moving forward with std::mutex. Hence, there is no real
reason to punt on making std::jthread & friends non-experimental.
2024-09-12 09:48:59 -04:00
David Spickett
5bd3ee0ac0 [libcxx][test] Use long double test macro in strong_order.pass.cpp (#106742) 2024-09-02 09:06:14 +01:00
David Spickett
c792de28df [libcxx][test] Add macro for when long double is just double (#106708)
This removes the need for the long list of platforms in
strong_order_long_double_verify.
2024-08-30 15:05:29 +01:00
A. Jiang
7808541fde [libc++] P2747R2: constexpr placement new (library part) (#105768)
This patch implements https://wg21.link/P2747R2.

The library changes affect direct `operator new` and `operator new[]`
calls even when the core language changes are absent.

The changes are not available for MS ABI because the `operator new` and
`operator new[]` are from VCRuntime's `<vcruntime_new.h>`. A feature
request was submitted for that [1].

As a drive-by change, the patch reformatted the whole `new.pass.cpp` and
`new_array.pass.cpp` tests.

Closes #105427

[1]: https://developercommunity.visualstudio.com/t/constexpr-for-placement-operator-newope/10730304.
2024-08-28 09:35:57 -04:00
A. Jiang
026210e80d [libc++][ranges] P2609R3: Relaxing Ranges Just A Smidge (#101715)
This patch implements https://wg21.link/p2609r3.
The test code was originally authored by JMazurkiewicz.

Notes:
- P2609R3 is not officially a Defect Report, but MSVC STL
  implements it in C++20 mode.

  Moreover, P2609R3 and P2997R1 touch exactly the same set of
  concepts, and MSVC STL and libc++ have already treated P2997R1
  as a DR.

- This patch also adjusted feature-test macros.
  + In C++20 mode, the value of __cpp_lib_ranges should be `202110L` because
    - `202202L` covers `range_adaptor_closure` (P2387R3), and
    - `202207L` covers move-only types in range adaptors (P2494R2).
  And all of these changes are only available since C++23 mode.

  + In C++23 mode, the value should be `202406L` because
    - `202211L` covers removing poison overloads (P2602R2),
    - `202302L` covers relaxing projected value types (P2609R3), and
    - `202406L` covers removing requirements on `iter_common_reference_t` (P2997R1).
  And all of these changes are already or being implemented.

Fixes #105253.

Co-authored-by: Jakub Mazurkiewicz <mazkuba3@gmail.com>
2024-08-28 08:55:44 -04:00
A. Jiang
4ea2c73886 [libc++] Deprecate and remove std::uncaught_exception (#101830)
Works towards P0619R4/#99985.

- std::uncaught_exception was not previously deprecated. This patch
  deprecates it since C++17 as per N4259. std::uncaught_exceptions is
  used instead as libc++ unconditionally provides this function.

- _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION restores
  std::uncaught_exception.

- As a drive-by, this patch updates the C++20 status page to 
  explain that D.11 is already done, since it was done in 
  578d09c1b1.
2024-08-27 17:15:03 -04:00
Louis Dionne
1c48c9cc43 [libc++] Implement P2985R0: std::is_virtual_base_of (#105847)
This trait is implemented in C++26 conditionally on the compiler
supporting the __builtin_is_virtual_base_of intrinsic. I believe only
tip-of-trunk Clang currently implements that builtin.

Closes #105432
2024-08-26 09:58:19 -04:00
Louis Dionne
aa08843878 [libc++] Avoid -Wzero-as-null-pointer-constant in operator<=> (#79465)
Issue #43670 describes a situation where the following comparison will
issue a warning when -Wzero-as-null-pointer-constant is enabled:

    #include <compare>
    auto b = (1 <=> 2) < 0;

This code uses operator<(strong_ordering, Unspecified), which is
specified by the Standard to only work with a literal 0. In the library,
this is achieved by constructing Unspecified from a pointer, which works
but has the downside of triggering the warning.

This patch uses an alternative implementation where we require that the
operator is used exactly with an int of value 0 (known at compile-time),
however that value can technically be an expression like `1 - 1`, which
makes us a bit less strict than what's specified in the Standard.

Fixes #43670
2024-08-21 09:05:55 -04:00
Mark de Wever
3ce6f68ee7 [libc++][spaceship] Marks P1614 as complete. (#99375)
Implements parts of:
- P1902R1 Missing feature-test macros 2017-2019

Completes:
- P1614R2 The Mothership has Landed

Fixes #100018
2024-07-25 18:37:36 +02:00
David Spickett
f87e9d42c7 [libcxx][test] Update picolibc version (#100348)
This is the latest as of today, and it fixes one of the xfails.

Since
5e4d0c80f4,
TIME_UTC is defined.
2024-07-25 10:24:51 +01:00
nicole mazzuca
04760bfadb [libc++][ranges] P1223R5: find_last (#99312)
Implements [P1223R5][] completely.

Includes an implementation of `find_last`, `find_last_if`, and
`find_last_if_not`.

[P1223R5]: https://wg21.link/p1223r5
2024-07-19 09:42:16 -07:00
Hristo Hristov
e475bb7ac3 [libc++][memory] P1132R8: out_ptr - a scalable output pointer abstraction (#73618)
Differential Revision: https://reviews.llvm.org/D150525

Implements:
- https://wg21.link/P1132R8 - `out_ptr` - a scalable output pointer
abstraction
- https://eel.is/c++draft/smartptr.adapt - 20.3.4 Smart pointer adaptors
- https://wg21.link/LWG3734 - Inconsistency in `inout_ptr` and `out_ptr`
for empty case
- https://wg21.link/LWG3897- `inout_ptr` will not update raw pointer to
0

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
2024-07-19 06:38:02 +03:00
Xing Xue
b7a6cca218 [libc++][test] XFAIL sized deallocation tests for AIX, z/OS, and MinGW (#98960)
The sized deallocation test cases fail on AIX, z/OS, and MinGW because
they default to `-fno-sized-deallocation`. This patch XFAILs these test
cases for the affected targets. Once they change the default, we will
get `unexpectedly pass`.
2024-07-18 06:32:14 -04:00
Hristo Hristov
4a19be5d45 [libc++][strings] P2591R5: Concatenation of strings and string views (#88389)
Implemented: https://wg21.link/P2591R5
- https://eel.is/c++draft/string.syn
- https://eel.is/c++draft/string.op.plus

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
2024-07-18 13:26:37 +03:00
Xiaoyang Liu
4e338dce4d [libc++] P2389R2: dextents Index Type Parameter (#97393)
This patch implements P2389R2, which was adopted at the St. Louis meeting.
It builds upon previous enhancements from P2299R3, which introduced deduction
guides and the `dextents` alias template.
2024-07-15 11:23:34 -04:00
Mark de Wever
deeb936863 [libc++][format] define __cpp_lib_format. (#98275)
In order to define the format __cpp_lib_format to its initial value
(201907) these papers need to be completed:
- P0645R10 Text Formatting
- P1652R1 Printf corner cases in std::format
- 1361R2 Integration of chrono with text formatting The first two have
been implemented for a while the latter is almost done.

The next value (202106) requires:
- P2216R3 std::format improvements which has been implemented

The next value (202110) requires:
- P2418R2 Add support for std::generator-like types to std::format
- P2372R3 Fixing locale handling in chrono formatters The first one has
been implemented for a while the latter is almost done. The latter paper
is a DR against 1361R2 and both are implemented at the same time.

We've had user feedback that the missing of the __cpp_lib_format makes
their lives harder (https://github.com/llvm/llvm-project/issues/77773).
The missing papers 1361R2 and P2372R3 are very close to completion and
might completed before LLVM-19, but it will be a close call. This has
been discussed in the monthly libc++ meeting and we decided to set the
__cpp_lib_format so it will be set in LLVM-19.

Based on the discussion and the implementation status the
__cpp_lib_format is set to 202110.

Fixes #77773
2024-07-10 17:52:43 +02:00
Louis Dionne
ad016352ec [libc++] Fix sized deallocation comments in tests (#98173)
Clang 19 turned on sized deallocation *by default*, but older versions
of Clang did support sized deallocation nonetheless. This updates a few
comments and removes UNSUPPORTED annotations that shouldn't be needed in
a test that passes -fsized-deallocation directly.
2024-07-10 09:53:03 -04:00
Louis Dionne
e42f760b65 [libc++] Define the __cpp_lib_atomic_ref feature test macro (#98081)
We forgot to enable it when we landed std::atomic_ref in 42ba740aff.
2024-07-09 11:08:29 -04:00
Mark de Wever
2dadf8d7f5 [libc++] Update status after the St. Louis meeting. (#97951)
This updates:
- The status tables
- Feature test macros
- New headers for modules
2024-07-08 19:35:31 +02:00
Mark de Wever
5aa8ef8e9b [libc++][test] Updates sized deallocation tests. (#97833)
In #90373 size deallocation was enabled by default. Some test were
disabled to propagate the clang changes to the libc++ CI. These changes
have been propagated so the test filter can be updated.
2024-07-06 11:56:11 +02:00
A. Jiang
0865b782f6 [libc++] Fix the signatures of std::rethrow_if_nested (#91365)
Fixes #54470.

See https://eel.is/c++draft/global.functions#2:
    > A call to a non-member function signature described in [support]
    > through [thread] and [depr] shall behave as if the implementation
    > declared no additional non-member function signatures.

and https://eel.is/c++draft/global.functions#3:
    > An implementation shall not declare a non-member function signature
    > with additional default arguments.
2024-07-03 10:51:23 -04:00
Louis Dionne
3497500946 [libc++] Clean up and update deployment target features (#96312)
This patch removes many annotations that are not relevant anymore since
we don't support or test back-deploying to macOS < 10.13. It also cleans
up raw usage of target triples to identify versions of dylibs shipped on
prior versions of macOS, and uses the target-agnostic Lit features
instead. Finally, it reorders both the Lit backdeployment features and
the corresponding availability macros in the library in a way that makes
more sense, and reformulates the Lit backdeployment features in terms of
when a version of LLVM was introduced instead of encoding the system
versions on which it hasn't been introduced yet. Although one can be
derived from the other, encoding the negative form is extremely
error-prone.

Fixes #80901
2024-06-28 10:40:35 -05:00
Louis Dionne
db8c7e004a [libc++] Fix deployment target Lit features (#94791)
We were not making any distinction between e.g. the "Apple-flavored"
libc++ built from trunk and the system-provided standard library on
Apple platforms. For example, any test that would be XFAILed on a
back-deployment target would unexpectedly pass when run on that
deployment target against the tip of trunk Apple-flavored libc++. In
reality, that test would be expected to pass because we're running
against the latest libc++, even if it is Apple-flavored.

To solve this issue, we introduce a new feature that describes whether
the Standard Library in use is the one provided by the system by
default, and that notion is different from the underlying standard
library flavor. We also refactor the existing Lit features to make a
distinction between availability markup and the library we're running
against at runtime, which otherwise limit the flexibility of what we can
express in the test suite. Finally, we refactor some of the
back-deployment versions that were incorrect (such as thinking that LLVM
10 was introduced in macOS 11, when in reality macOS 11 was synced with
LLVM 11).

Fixes #82107
2024-06-21 10:31:22 -04:00
Mark de Wever
759fb590da [libc++][modules] Mark as implemented. (#90091)
The feature has been implemented in LLVM 18 as an experimental feature.
This marks the paper as complete and sets the feature-test macro.

Implements
- P2465R3 Standard Library Modules std and std.compat

Fixes: https://github.com/llvm/llvm-project/issues/89579
2024-06-12 19:01:27 +02:00
Mark de Wever
c36961bd96 [libc++] Adds __cpp_lib_three_way_comparison FTM. (#91515)
The paper
  P0768R1 Library Support for the Spaceship (Comparison) Operator
did not add a feature-test macro. This omission has been corrected in
  P1353R0 Missing Feature Test Macros

This enables the FTM for P0768R1

Fixes: https://github.com/llvm/llvm-project/issues/73953

---------

Co-authored-by: S. B. Tam <cpplearner@outlook.com>
2024-06-12 18:59:21 +02:00
Louis Dionne
1d76b94aba [libc++] Adjust XFAIL for quick_exit (#94274)
This avoids making the assumption that quick_exit will never be
implemented on macOS.
2024-06-04 14:21:28 -04:00
Stephan T. Lavavej
a4bef0ca82 [libc++] Mark P2845R8 __cpp_lib_format_path and P2587R3 __cpp_lib_to_string as C++26 (#93255)
[P2845R8](https://wg21.link/P2845R8) "Formatting of
`std::filesystem::path`" and [P2587R3](https://wg21.link/P2587R3)
"`to_string` or not `to_string`" are C++26 features, so they should be
marked accordingly in `generate_feature_test_macro_components.py`.

I verified that without my changes, running the script produced no
edits. Then with my changes, I ran the script to regenerate all files,
with no other manual edits.

Found while running libc++'s tests with MSVC's STL, which noticed this
because it's currently a C++23-only implementation.

Note that @H-G-Hristov has a draft implementation of P2587R3: #78100
2024-05-28 12:15:50 -07:00
Pengcheng Wang
130e93cc26 Reland "[clang] Enable sized deallocation by default in C++14 onwards" (#90373)
Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

The original commit cf5a8b4 was reverted by 2e5035a due to some
failures (see #83774).

Fixes #60061
2024-05-22 12:37:27 +08:00
Mital Ashok
8f711aa324 [libc++][test] __cpp_lib_within_lifetime -> __cpp_lib_is_within_lifetime (#91896)
The feature test macro was renamed when
[P2641R4](https://wg21.link/P2641R4) was adopted into the standard:
0facada4ca
https://wg21.link/version.syn#lib:__cpp_lib_is_constant_evaluated
2024-05-16 09:45:45 +02:00
Hristo Hristov
8afa6cf510 [libc++][functional] P2944R3 (partial): Comparisons for reference_wrapper (reference_wrapper operators only) (#88384)
Implements https://wg21.link/P2944R3 (partially)
Implements https://wg21.link/LWG4071 /
https://cplusplus.github.io/LWG/issue4071 (fixes build failures in the
test suite)
- https://eel.is/c++draft/refwrap.comparisons
2024-05-09 12:48:37 +03:00
krzysdz
028f1b0781 [libc++] Fix P1206R7 feature test macros (#90914)
- Add missing `__cpp_lib_containers_ranges` feature test macro
- Constrain `__cpp_lib_ranges_to_container` to the `<ranges>` header,
since the standard does not list it in containers' headers

Ref:
-
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1206r7.pdf#section.18
- https://eel.is/c++draft/support.limits#lib:__cpp_lib_containers_ranges
-
https://eel.is/c++draft/support.limits#lib:__cpp_lib_ranges_to_container
2024-05-04 18:23:49 +02:00
Jack Styles
c3598b161a [libc++] Improve libc++ tests when using optimizations (#88897)
Some tests were missing DoNotOptimize annotations.
2024-04-29 12:33:25 -06:00
Vitaly Buka
2e5035aeed Revert "[clang] Enable sized deallocation by default in C++14 onwards (#83774)" (#90299)
https://lab.llvm.org/buildbot/#/builders/168/builds/20063 (should be
fixed with #90292)

More details in #83774

This reverts commit cf5a8b4894.
2024-04-26 17:14:43 -07:00
Aaron Ballman
72c373bfdc [C++17] Support __GCC_[CON|DE]STRUCTIVE_SIZE (#89446)
These macros are used by STL implementations to support implementation
of std::hardware_destructive_interference_size and
std::hardware_constructive_interference_size

Fixes #60174

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2024-04-26 12:05:15 -04:00
Pengcheng Wang
cf5a8b4894 [clang] Enable sized deallocation by default in C++14 onwards (#83774)
Since C++14 has been released for about nine years and most standard
libraries have implemented sized deallocation functions, it's time to
make this feature default again.

This is another try of https://reviews.llvm.org/D112921.

Fixes #60061
2024-04-26 16:59:12 +08:00
Nikolas Klauser
83bc7b5771 [libc++] Remove _LIBCPP_DISABLE_NODISCARD_EXTENSIONS and refactor the tests (#87094)
This also adds a few tests that were missing.
2024-04-22 22:13:58 +02:00
Jakub Mazurkiewicz
c8917048e3 [libc++] Implement bind_back (#81055)
Implement `std::bind_back` function from P2387R3 "Pipe support for
user-defined range adaptors".
2024-04-09 11:10:20 -04:00
Louis Dionne
b699a9ba11 [libc++] Update status page after the Tokyo meeting (#87395) 2024-04-03 08:21:11 -04:00
Hristo Hristov
80f9458cf3 [libc++][sstream] P2495R3: Interfacing stringstreams with string_view (#80552)
Implements P2495R3 <https://wg21.link/P2495R3>
- https://eel.is/c++draft/version.syn#headerref:%3csstream%3e
- https://eel.is/c++draft/stringbuf
- https://eel.is/c++draft/stringbuf.general
- https://eel.is/c++draft/stringbuf.cons
- https://eel.is/c++draft/stringbuf.members
- https://eel.is/c++draft/istringstream
- https://eel.is/c++draft/istringstream.general
- https://eel.is/c++draft/istringstream.cons
- https://eel.is/c++draft/istringstream.members
- https://eel.is/c++draft/ostringstream
- https://eel.is/c++draft/ostringstream.general
- https://eel.is/c++draft/ostringstream.cons
- https://eel.is/c++draft/ostringstream.members
- https://eel.is/c++draft/stringstream
- https://eel.is/c++draft/stringstream.general
- https://eel.is/c++draft/stringstream.cons
- https://eel.is/c++draft/stringstream.members

References:
- https://eel.is/c++draft/string.streams
2024-03-05 08:49:49 +02:00
ZijunZhaoCCK
7d7d4752a8 [libc++] Set feature test macros __cpp_lib_ranges_contains and__cpp_lib_ranges_starts_ends_with (#81816)
ranges::contains: fdd089b500
ranges::starts_with: 205175578e
ranges::ends_with: 0218ea4aaa

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2024-02-29 16:06:32 -08:00
Abhina Sree
1197fcabc4 [libcxx][test] Change UNSUPPORTED to XFAIL for target-related failures (#81513)
This is a followup from this discussion
https://github.com/llvm/llvm-project/pull/80735#discussion_r1486586017
to mark targets that were initially marked as UNSUPPORTED with an XFAIL
instead.
2024-02-23 08:01:56 -05:00
Abhina Sree
a70077ed8c [SystemZ][z/OS][libcxx] mark aligned allocation tests XFAIL on z/OS (#80735)
zOS doesn't support aligned allocation, so mark these testcases as
unsupported.

Continuation of https://reviews.llvm.org/D102798
2024-02-13 08:03:14 -05:00
Louis Dionne
f2c84211d2 [libc++] Add missing conditionals for feature-test macros (#80168)
We noticed that some feature-test macros were not conditional on
configuration flags like _LIBCPP_HAS_NO_FILESYSTEM. As a result, code
attempting to use FTMs would not work as intended.

This patch adds conditionals for a few feature-test macros, but more
issues may exist.

rdar://122020466
2024-02-05 11:05:46 -05:00
Hristo Hristov
7d78ccf7d5 [libc++][memory] P2652R2: Disallow Specialization of allocator_traits (#79978)
Implements P2652R2 <https://wg21.link/P2652R2>:
- https://eel.is/c++draft/allocator.requirements.general
- https://eel.is/c++draft/memory.syn
- https://eel.is/c++draft/allocator.traits.general
- https://eel.is/c++draft/allocator.traits.members
- https://eel.is/c++draft/diff.cpp20.concepts
- https://eel.is/c++draft/diff.cpp20.utilities

---------

Co-authored-by: Zingam <zingam@outlook.com>
2024-02-01 12:31:25 +01:00
Louis Dionne
314526557e [libc++] Fix the behavior of throwing operator new under -fno-exceptions (#69498)
In D144319, Clang tried to land a change that would cause some functions
that are not supposed to return nullptr to optimize better. As reported
in https://reviews.llvm.org/D144319#4203982, libc++ started seeing
failures in its CI shortly after this change was landed.

As explained in D146379, the reason for these failures is that libc++'s
throwing `operator new` can in fact return nullptr when compiled with
exceptions disabled. However, this contradicts the Standard, which
clearly says that the throwing version of `operator new(size_t)` should
never return nullptr. This is actually a long standing issue. I've
previously seen a case where LTO would optimize incorrectly based on the
assumption that `operator new` doesn't return nullptr, an assumption
that was violated in that case because libc++.dylib was compiled with
-fno-exceptions.

Unfortunately, fixing this is kind of tricky. The Standard has a few
requirements for the allocation functions, some of which are impossible
to satisfy under -fno-exceptions:
1. `operator new(size_t)` must never return nullptr
2. `operator new(size_t, nothrow_t)` must call the throwing version and
return nullptr on failure to allocate
3. We can't throw exceptions when compiled with -fno-exceptions

In the case where exceptions are enabled, things work nicely.
`new(size_t)` throws and `new(size_t, nothrow_t)` uses a try-catch to
return nullptr. However, when compiling the library with
-fno-exceptions, we can't throw an exception from `new(size_t)`, and we
can't catch anything from `new(size_t, nothrow_t)`. The only thing we
can do from `new(size_t)` is actually abort the program, which does not
make it possible for `new(size_t, nothrow_t)` to catch something and
return nullptr.

This patch makes the following changes:
1. When compiled with -fno-exceptions, the throwing version of `operator
new` will now abort on failure instead of returning nullptr on failure.
This resolves the issue that the compiler could mis-compile based on the
assumption that nullptr is never returned. This constitutes an API and
ABI breaking change for folks compiling the library with -fno-exceptions
(which is not the general public, who merely uses libc++ headers but use
a shared library that has already been compiled). This should mostly
impact vendors and other folks who compile libc++.dylib themselves.

2. When the library is compiled with -fexceptions, the nothrow version
of `operator new` has no change. When the library is compiled with
-fno-exceptions, the nothrow version of `operator new` will now check
whether the throwing version of `operator new` has been overridden. If
it has not been overridden, then it will use an implementation
equivalent to that of the throwing `operator new`, except it will return
nullptr on failure to allocate (instead of terminating). However, if the
throwing `operator new` has been overridden, it is now an error NOT to
also override the nothrow `operator new`. Indeed, there is no way for us
to implement a valid nothrow `operator new` without knowing the exact
implementation of the throwing version.

In summary, this change will impact people who fall into the following
intersection of conditions:
- They use the libc++ shared/static library built with `-fno-exceptions`
- They do not override `operator new(..., std::nothrow_t)`
- They override `operator new(...)` (the throwing version)
- They use `operator new(..., std::nothrow_t)`

We believe this represents a small number of people.

Fixes #60129
rdar://103958777

Differential Revision: https://reviews.llvm.org/D150610
2024-01-22 22:33:04 -05:00