155 Commits

Author SHA1 Message Date
Konstantin Varlamov
000d2b8582 [libc++][hardening][NFC] Rework the Lit feature for detecting the hardening mode.
Make it a multichoice string to closer mirror the CMake variable. This
allows writing `UNSUPPORTED: libcpp-hardening-mode=unchecked` rather
than `UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode`.

Differential Revision: https://reviews.llvm.org/D155906
2023-08-04 00:21:55 -07:00
varconst
66bd177a77 [libc++][hardening] Don't trigger uncategorized assertions in the hardened mode.
The hardened mode is intended to only include security-critical,
relatively low-overhead checks that are intended to be usable in
production. By default, assertions are excluded from this mode.

Differential Revision: https://reviews.llvm.org/D155866
2023-07-20 22:50:52 -07:00
Nikolas Klauser
37e5baf318 [libc++][PSTL] Implement std::sort
Reviewed By: #libc, ldionne

Spies: ldionne, libcxx-commits, mgrang

Differential Revision: https://reviews.llvm.org/D152860
2023-07-20 14:45:36 -07:00
varconst
f0dfe682bc [libc++][hardening] Deprecate _LIBCPP_ENABLE_ASSERTIONS.
`_LIBCPP_ENABLE_ASSERTIONS` was used to enable the "safe" mode in
libc++. Libc++ now provides the hardened mode and the debug mode that
replace the safe mode.

For backward compatibility, enabling `_LIBCPP_ENABLE_ASSERTIONS` now
enables the hardened mode. Note that the hardened mode provides
a narrower set of checks than the previous "safe" mode (only
security-critical checks that are performant enough to be used in
production).

Differential Revision: https://reviews.llvm.org/D154997
2023-07-14 16:58:47 -07:00
Nikolas Klauser
2b2e7f6e57 [libc++][PSTL] Add a GCD backend
Reviewed By: ldionne, #libc

Spies: arichardson, mgrang, krytarowski, libcxx-commits, h-vetinari

Differential Revision: https://reviews.llvm.org/D151717
2023-07-12 13:27:33 -07:00
varconst
d1367ca46e [libc++][hardening][NFC] Add macros to enable hardened mode.
This patch only adds new configuration knobs -- the actual assertions
will be added in follow-up patches.

Differential Revision: https://reviews.llvm.org/D153902
2023-07-12 10:12:58 -07:00
Nikolas Klauser
ece2294b9a [libc++][PSTL] Add a missing policy argument in the std::merge test
Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D154546
2023-07-07 15:41:41 -07:00
Louis Dionne
b82dcb624e [libc++] Move all the remaining .fail.cpp tests to .verify.cpp
I made sure they all had some expected-error output in them. Many of
these tests would be better implemented as a positive test using SFINAE,
but this is beyond the scope of this patch.

Differential Revision: https://reviews.llvm.org/D153980
2023-07-03 09:41:03 -04:00
varconst
b5270ba20d [libc++] Remove the legacy debug mode.
See https://discourse.llvm.org/t/rfc-removing-the-legacy-debug-mode-from-libc/71026

Reviewed By: #libc, Mordante, ldionne

Differential Revision: https://reviews.llvm.org/D153672
2023-06-29 14:49:51 -07:00
Nikolas Klauser
3a7876f6e2 [libc++][PSTL] Implement std::is_partitioned
Reviewed By: #libc, ldionne

Spies: ldionne, libcxx-commits

Differential Revision: https://reviews.llvm.org/D152853
2023-06-15 11:23:07 -07:00
Nikolas Klauser
b935ab8e74 [libc++] Add tests to make sure that stable algorithms work without memory available
Reviewed By: #libc, ldionne

Spies: power-llvm-team, ldionne, libcxx-commits, arichardson, mstorsjo

Differential Revision: https://reviews.llvm.org/D152939
2023-06-15 10:59:34 -07:00
Louis Dionne
3456b2f60a [libc++] Refactor __debug_three_way_comp
This makes __debug_three_way_comp consistent with __debug_less and
in particular gets rid of a potential use-after-move caused by the
use of std::forward. In the previous version of the code, we would
call `__do_compare_assert` after forwarding the arguments into the
comparator, which could end up using the arguments after they've been
moved from.

This also simplifies how we call `__do_compare_assert` by using
`if constexpr` and adds a missing test for proxy iterators in
lexicographical_compare_three_way, which could have found this
issue.

Differential Revision: https://reviews.llvm.org/D152753
2023-06-13 14:24:56 -07:00
Louis Dionne
520c7fbbd0 [libc++] Mark slow tests as unsupported on GCC
Some tests in our test suite are unbelievably slow on GCC due to the
use of the always_inline attribute. See [1] for more details.

This patch introduces the GCC-ALWAYS_INLINE-FIXME lit feature to
disable tests that are plagued by that issue. At the same time, it
moves several existing tests from ad-hoc `UNSUPPORTED: gcc-12` markup
to the new GCC-ALWAYS_INLINE-FIXME feature, and marks the slowest tests
reported by the CI as `UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME`.

[1]: https://discourse.llvm.org/t/rfc-stop-supporting-extern-instantiations-with-gcc/71277/1

Differential Revision: https://reviews.llvm.org/D152736
2023-06-13 10:20:30 -07:00
Hristo Hristov
8fe609cb3a [libc++][spaceship] Fixed __debug_three_way_comp's operator() for vector<bool>'s operator<=>`
An issue with `operator()` was found during the implementation of https://reviews.llvm.org/D132268.

This patch aims to resolve the issues by updating the operator to use perfect forwarding.

The original motivation for `three_way_comp_ref_type` is given in: https://reviews.llvm.org/D131395

`three_way_comp_ref_type`'s implementation is inspired by `comp_ref_type`, which has two overloads:

```
    template <class _Tp, class _Up>
    bool operator()(const _Tp& __x,  const _Up& __y);

    template <class _Tp, class _Up>
    bool operator()(_Tp& __x,  _Up& __y);
```

`__debug_three_way_comp` is missing the first overload and also declares the typealias`_three_way_comp_ref_type ` incorrectly.

Reviewed By: #libc, philnik

Differential Revision: https://reviews.llvm.org/D150188
2023-06-10 06:48:01 +03:00
Danila Kutenin
7e1ee1e10d [libcxx] Add strict weak ordering checks to sorting algorithms
This is the implementation of the first proposal of strict weak ordering checks described in https://discourse.llvm.org/t/rfc-strict-weak-ordering-checks-in-the-debug-libc/70217

This targets the most vulnerable algorithms like std::sort

Reviewed By: philnik, #libc

Differential Revision: https://reviews.llvm.org/D150264
2023-06-04 19:27:31 +02:00
Nikolas Klauser
d51a84b405 [libc++][PSTL] Implement std::stable_sort
Reviewed By: #libc, ldionne

Spies: ldionne, libcxx-commits

Differential Revision: https://reviews.llvm.org/D151573
2023-06-01 15:07:28 -07:00
Nikolas Klauser
bf63b15bd4 [libc++][PSTL] Implement std::merge
Reviewed By: ldionne, #libc

Spies: pcwang-thead, libcxx-commits

Differential Revision: https://reviews.llvm.org/D151375
2023-05-30 15:07:06 -07:00
Louis Dionne
f0fc8c4878 [libc++] Use named Lit features to flag back-deployment XFAILs
Instead of writing something like `XFAIL: use_system_cxx_lib && target=...`
to XFAIL back-deployment tests, introduce named Lit features like
`availability-shared_mutex-missing` to represent those. This makes the
XFAIL annotations leaner, and solves the problem of XFAIL comments
potentially getting out of sync. This would also make it easier for
another vendor to add their own annotations to the test suite by simply
changing how the feature is defined for their OS releases, instead
of having to modify hundreds of tests to add repetitive annotations.

This doesn't touch *all* annotations -- only annotations that were widely
duplicated are given named features (e.g. when filesystem or shared_mutex
were introduced). I still think it probably doesn't make sense to have a
named feature for every single fix we make to the dylib.

This is in essence a revert of 2659663, but since then the test suite
has changed significantly. Back when I did 2659663, the configuration
files we have for the test suite right now were being bootstrapped and
it wasn't clear how to provide these features for back-deployment in
that context. Since then, we have a streamlined way of defining these
features in `features.py` and that doesn't impact the ability for a
configuration file to stay minimal.

The original motivation for this change was that I am about to propose
a change that would touch essentially all XFAIL annotations for back-deployment
in the test suite, and this greatly reduces the number of lines changed
by that upcoming change, in addition to making the test suite generally
better.

Differential Revision: https://reviews.llvm.org/D146359
2023-03-27 12:44:26 -04:00
Mark de Wever
fb855eb941 [libc++] Qualifies size_t.
This has been done using the following command

  find libcxx/test -type f -exec perl -pi -e 's|^([^/]+?)((?<!::)size_t)|\1std::\2|' \{} \;

And manually removed some false positives in std/depr/depr.c.headers.

The `std` module doesn't export `::size_t`, this is a preparation for that module.

Reviewed By: ldionne, #libc, EricWF, philnik

Differential Revision: https://reviews.llvm.org/D146088
2023-03-21 17:41:36 +01:00
Nikolas Klauser
aff3cdc604 [libc++] Optimize std::ranges::{min, max} for types that are cheap to copy
Don't forward to `min_element` for small types that are trivially copyable, and instead use a naive loop that keeps track of the smallest element (as opposed to an iterator to the smallest element). This allows the compiler to vectorize the loop in some cases.

Reviewed By: #libc, ldionne

Spies: ldionne, libcxx-commits

Differential Revision: https://reviews.llvm.org/D143596
2023-03-11 16:28:24 +01:00
Nikolas Klauser
33912468a7 [libc++] Fix ranges::binary_search() returning true for cases where the element is not in the range
Fixes #61160

Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D145287
2023-03-07 17:23:23 +01:00
Nilay Vaish
1edc72385a Checked that complexity of std::sort_heap is 2N log(N) comparisons
https://wg21.link/LWG2444 updated the comparison complexity of
std:sort_heap to be at most 2N log (N) where N == last - first.  In the
current implementation, we invoke __pop_heap exactly N-1 times.  In each
call to __pop_heap, we first go down the heap from first to possibly
last in the function __floyd_sift_down.  Then, we possibly go back up in
the function __sift_up.

In the function __floyd_sift_down, there is loop in which one comparison
is made in each iteration.  The loop runs till __child becomes greater
than (__len - 2) / 2.  __child starts at 0 and it is at least set to 2 *
__child + 1 on each iteration.  Thus, after k iterations, __child will
be at least 2^k - 1.  After log(N) iterations,  __child >= 2^(log(N)) -
1 = N - 1 > (__len - 2) / 2.  This means that the while loop in the
function __floyd_sift_down would perform at most log(N) comparisons on
each invocation.

In the function __sift_up, there is one comparison made that will almost
always occur.  After that there is a do-while loop.  The comparison
function is invoked once in each iteration.  In the worst case, the loop
will run till __len goes down to zero.  It can start from (N-3)/2.  In
each iteration, __len goes down to (__len-1) / 2.  After k iterations,
__len will be at most (N - 2^(k+1) -1) / 2^(k+1).  Thus, __len will
become  when (N-2^(k+1)-1) < 2^(k+1)  i.e. N  < 2^(k+2) + 1.  This means
at most log(N) - 1 iterations for the loop.  So in total at most log(N)
  comparison will be performed in __sift_up.

So overall for each iteration of the loop in __pop_heap, there will at
most 2 log(N) comparisons.  So, the total number of comparisons is
at most 2 N log(N).

We also updated the test sort.heap/complexity.pass.cpp to test for the
number of operations.

Differential Revision: https://reviews.llvm.org/D144538
2023-03-06 08:42:25 -08:00
Igor Zhukov
0a0d58f546 [libc++] <algorithm>: ranges::minmax should dereference iterators only once
Reviewed By: philnik, #libc

Differential Revision: https://reviews.llvm.org/D142864
2023-02-15 06:02:12 +07:00
Adrian Vogelsgesang
2a06757a20 [libc++][spaceship] Implement lexicographical_compare_three_way
The implementation makes use of the freedom added by LWG 3410. We have
two variants of this algorithm:
* a fast path for random access iterators: This fast path computes the
  maximum number of loop iterations up-front and does not compare the
  iterators against their limits on every loop iteration.
* A basic implementation for all other iterators: This implementation
  compares the iterators against their limits in every loop iteration.
  However, it still takes advantage of the freedom added by LWG 3410 to
  avoid unnecessary additional iterator comparisons, as originally
  specified by P1614R2.

https://godbolt.org/z/7xbMEen5e shows the benefit of the fast path:
The hot loop generated of `lexicographical_compare_three_way3` is
more tight than for `lexicographical_compare_three_way1`. The added
benchmark illustrates how this leads to a 30% - 50% performance
improvement on integer vectors.

Implements part of P1614R2 "The Mothership has Landed"

Fixes LWG 3410 and LWG 3350

Differential Revision: https://reviews.llvm.org/D131395
2023-02-12 14:51:08 -08:00
Louis Dionne
396fbe264f [libc++] Bump AppleClang compiler requirement
Per our policy, the latest released AppleClang has been 14 for a while,
so libc++ is removing support for AppleClang 13. Our CI bots have been
moved to AppleClang 14 a few weeks ago.

Differential Revision: https://reviews.llvm.org/D138685
2022-11-25 09:51:44 -05:00
Nikolas Klauser
89b356f05a [libc++] Granularize <concept> includes
Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D137283
2022-11-05 20:59:29 +01:00
Nikolas Klauser
660b243120 [libc++] Add [[nodiscard]] extensions to ranges algorithms
This mirrors what we have done in the classic algorithms

Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D137186
2022-11-05 16:38:46 +01:00
Nikolas Klauser
7afa1598a3 [libc++] Avoid including <tuple> in compressed_pair.h
compressed_pair is widely used in the library, but most of the uses don't use the tuple parts. To avoid including <tuple> everywhere, use the forward declaration instead in compressed_pair.h

Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D133331
2022-09-18 10:49:35 +02:00
Nikolas Klauser
d5e26775d0 [libc++] Granularize the rest of memory
Reviewed By: ldionne, #libc

Spies: vitalybuka, paulkirth, libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D132790
2022-09-05 12:36:41 +02:00
Vitaly Buka
bc8fd9c633 Revert "[libc++] Granularize the rest of memory"
Breaks buildbots.

This reverts commit 30adaa730c4768b5eb06719c808b2884fcf53cf3.
2022-09-02 19:42:49 -07:00
Nikolas Klauser
30adaa730c [libc++] Granularize the rest of memory
Reviewed By: ldionne, #libc

Spies: libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D132790
2022-09-02 21:42:41 +02:00
Nikolas Klauser
3c355e2881 [libc++] Enable [[nodiscard]] extensions by default
Adding `[[nodiscard]]` to functions is a conforming extension and done extensively in the MSVC STL.

Reviewed By: ldionne, EricWF, #libc

Spies: #libc_vendors, cjdb, mgrang, jloser, libcxx-commits

Differential Revision: https://reviews.llvm.org/D128267
2022-09-02 21:34:20 +02:00
Louis Dionne
355e0ce3c5 [libc++] Extend check for non-ASCII characters to src/, test/ and benchmarks/
Differential Revision: https://reviews.llvm.org/D132180
2022-08-23 18:36:38 -04:00
Louis Dionne
89469df8ba [libc++] Remove trailing whitespace from libcxx includes, source, tests and benchmarks
Differential Revision: https://reviews.llvm.org/D132175
2022-08-23 18:25:54 -04:00
Louis Dionne
b8cb1dc9ea [libc++] Make <ranges> non-experimental
When we ship LLVM 16, <ranges> won't be considered experimental anymore.
We might as well do this sooner rather than later.

Differential Revision: https://reviews.llvm.org/D132151
2022-08-18 16:59:58 -04:00
Nikolas Klauser
4038c859e5 [libc++][ranges] Implement ranges::is_permutation
Co-authored-by: Konstantin Varlamov <varconst@apple.com>

Differential Revision: https://reviews.llvm.org/D127194
2022-08-04 10:54:37 -07:00
Nikolas Klauser
a203acb9dd [libc++][ranges] Implement ranges::clamp
Differential Revision: https://reviews.llvm.org/D126193
2022-08-04 02:45:32 -07:00
Nikolas Klauser
68264b6494 [libc++][ranges] Implement ranges::{prev, next}_permutation.
Co-authored-by: Konstantin Varlamov <varconst@apple.com>

Differential Revision: https://reviews.llvm.org/D129859
2022-08-02 22:46:15 -07:00
Konstantin Varlamov
db7d795978 [libc++][ranges] Implement std::ranges::partial_sort_copy.
Differential Revision: https://reviews.llvm.org/D130532
2022-07-30 02:42:18 -07:00
Hui Xie
8a61749f76 [libc++][ranges] implement std::ranges::inplace_merge
Differential Revision: https://reviews.llvm.org/D130627
2022-07-28 08:37:48 +01:00
Konstantin Varlamov
8e26c315a7 [libc++][NFC] Add checks for lifetime issues in classic algorithms.
Differential Revision: https://reviews.llvm.org/D130330
2022-07-26 16:15:11 -07:00
Konstantin Varlamov
d406c6493e [libc++][ranges] Implement ranges::is_heap{,_until}.
Differential Revision: https://reviews.llvm.org/D130547
2022-07-26 16:11:24 -07:00
Hui Xie
c559964d85 [libc++][ranges] implement std::ranges::includes
implement `std::ranges::includes` and delegate to `std::includes`

Differential Revision: https://reviews.llvm.org/D130116
2022-07-22 10:27:48 +01:00
Hui Xie
0f6364b8a1 [libc++][ranges] implement std::ranges::equal_range
implement `std::ranges::equal_range` which delegates to
`std::equal_range`

Differential Revision: https://reviews.llvm.org/D129796
2022-07-22 10:24:08 +01:00
Hui Xie
7abbd6224b [libc++] Fix proxy iterator issues that trigger an assertion in Chromium.
Crash report:
https://bugs.chromium.org/p/chromium/issues/detail?id=1346012

The triggered assertion is related sorting with `v8::internal::AtomicSlot`.
`AtomicSlot` is a proxy iterator with a proxy type `AtomicSlot::Reference`
(see 9bcb5eb590/src/objects/slots-atomic-inl.h).

https://reviews.llvm.org/D130197 correctly spotted the issue in
`__iter_move` but doesn't actually fix the issue. The reason is that
`AtomicSlot::operator*` returns a prvalue `Reference`. After the fix in
D130197, the return type of `__iter_move` is `Reference&&`. But the
rvalue reference is bound to the temporary value returned by
`operator*`, which will be dangling after `__iter_move` returns.

The idea of the fix in this change is borrowed from C++17's move_iterator
https://timsong-cpp.github.io/cppwp/n4659/move.iterators#move.iterator-1
When the underlying reference is a prvalue, we just return it by value.

Differential Revision: https://reviews.llvm.org/D130212
2022-07-20 18:05:49 -07:00
Konstantin Varlamov
bc4d2e7051 [libc++] Fix _IterOps::__iter_move to support proxy iterators.
The return type was specified incorrectly for proxy iterators that
define `reference` to be a class that implicitly converts to
`value_type`. `__iter_move` would end up returning an object of type
`reference` which would then implicitly convert to `value_type`; thus,
the function will return a `value_type&&` rvalue reference to the local
temporary.

Differential Revision: https://reviews.llvm.org/D130197
2022-07-20 13:19:00 -07:00
varconst
5dd19ada57 [libc++][ranges] Implement ranges::partial_sort.
Differential Revision: https://reviews.llvm.org/D128744
2022-07-19 20:10:34 -07:00
Louis Dionne
8711fcae27 [libc++] Treat incomplete features just like other experimental features
In particular remove the ability to expel incomplete features from the
library at configure-time, since this can now be done through the
_LIBCPP_ENABLE_EXPERIMENTAL macro.

Also, never provide symbols related to incomplete features inside the
dylib, instead provide them in c++experimental.a (this changes the
symbols list, but not for any configuration that should have shipped).

Differential Revision: https://reviews.llvm.org/D128928
2022-07-19 10:50:20 -04:00
Hui Xie
3151b95dad [libc++][ranges] implement std::ranges::set_union
[libc++][ranges] implement `std::ranges::set_union`

Differential Revision: https://reviews.llvm.org/D129657
2022-07-14 21:05:30 +01:00
Hui Xie
a5c0638dec [libc++][ranges] implement std::ranges::set_symmetric_difference
[libc++][ranges] implement `std::ranges::set_symmetric_difference`

Differential Revision: https://reviews.llvm.org/D129520
2022-07-13 21:24:32 +01:00