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
This patch hardens the "test iterators" we use to test algorithms by
ensuring that they don't get double-moved. As a result of this
hardening, the tests started reporting multiple failures where we would
double-move iterators, which are being fixed in this patch.
In particular:
- Fixed a double-move in pstl.partition
- Add coverage for begin()/end() in subrange tests
- Fix tests for ranges::ends_with and ranges::contains, which were
incorrectly calling begin() twice on the same subrange containing
non-copyable input iterators.
Fixes#100709
Following up on https://github.com/llvm/llvm-project/pull/98841.
Changes:
- Properly test convertible types for `std::isnan()` and `std::inf()`
- Tighten conditional in `cmath.pass.cpp` (Find insights on `_LIBCPP_PREFERRED_OVERLOAD` below)
- Tighten preprocessor guard in `traits.h`
Insights into why `_LIBCPP_PREFERRED_OVERLOAD` is needed:
(i) When libc++ is layered on top of glibc on Linux, glibc's `math.h` is
included. When compiling with `-std=c++03`, this header brings the
function declaration of `isinf(double)` [1] and `isnan(double)` [2]
into scope. This differs from the C99 Standard as only the macros
`#define isnan(arg)` and `#define isinf(arg)` are expected.
Therefore, libc++ needs to respect the presense of the `double` overload
and cannot redefine it as it will conflict with the declaration already
in scope. For `-std=c++11` and beyond this issue is fixed, as glibc
guards both the `isinf` and `isnan` by preprocessor macros.
(ii) When libc++ is layered on top of Bionic's libc, `math.h` exposes a
function prototype for `isinf(double)` with return type `int`. This
function prototype in Bionic's libc is not guarded by any preprocessor
macros [3].
`_LIBCPP_PREFERRED_OVERLOAD` specifies that a given overload is a better match
than an otherwise equally good function declaration. This is implemented in
modern versions of Clang via `__attribute__((__enable_if__))`, and not elsewhere.
See [4] for details. We use `_LIBCPP_PREFERRED_OVERLOAD` to define overloads in
the global namespace that displace the overloads provided by the C
libraries mentioned above.
[1]: fe94080875/math/bits/mathcalls.h (L185-L194)
[2]: fe94080875/math/bits/mathcalls.h (L222-L231)
[3]: https://cs.android.com/android/platform/superproject/+/master:bionic/libc/include/math.h;l=322-323;drc=master?hl=fr-BE%22https:%2F%2Fsupport.google.com%2Fmerchants%2Fanswer%2F188494%5C%22%22https:%2F%2Fsupport.google.com%2Fmerchants%2Fanswer%2F188494%5C%22
[4]: 5fd17ab1b0
Trying to copy-construct a std::span from another std::span holding an
incomplete type would fail as we evaluate the SFINAE for the range-based
constructor. The problem was that we checked for __is_std_span after
checking for the range being a contiguous_range, which hard-errored
because of arithmetic on a pointer to incomplete type.
As a drive-by, refactor the whole test and format it.
Fixes#104496
Various functions like hash_value, lexically_proximate and lexically_relative
would incorrectly handle backslashes in the root directory on Windows, causing
behavior that is inconsistent with the equality comparison for a path.
Until https://github.com/llvm/llvm-project/pull/103056 lands
or another more appropriate check can be found.
This test fails on Ubuntu Focal where zdump is built with 32 bit time_t
but passes on Ubuntu Jammy where zdump is built with 64 bit time_t.
Marking it unsupported means Linaro can upgrade its bots to Ubuntu
Jammy without getting an unexpected pass.
I had originally made some comments in https://reviews.llvm.org/D128214
that were followed when we implemented LWG2762. I don't understand why I
made these comments anymore, but either way it seems like I was wrong
since using `unique_ptr<void>::operator*` should be ill-formed. All
other implementations also make that ill-formed.
## Introduction
This patch implements LWG3564:
`transform_view::iterator<true>::value_type` and `iterator_category`
should use `const F&`.
`transform_view`'s iterator currently obtained from a `const
transform_view` invoke the transformation function as `const`, but the
`value_type` and `iterator_category` determination uses non-`const`
`F&`.
## Reference
-
[[range.transform.iterator]](https://eel.is/c++draft/range.transform.iterator)
- [LWG3564](https://cplusplus.github.io/LWG/issue3564)
The HEX float on z/OS does not have infinity nor NaN. In addition, the
limits are smaller before the overflow occurs in mathematical
calculations. This PR accounts for this.
FYI, this LIT test was recently added in PR
[89982](https://github.com/llvm/llvm-project/pull/89982)
This adds addressof at the required places in [input.output]. Some of
the new tests failed since string used operator& internally. These have
been fixed too.
Note the new fstream tests perform output to a basic_string instead of a
double. Using a double requires num_get specialization
num_get<CharT, istreambuf_iterator<CharT,
char_traits_operator_hijacker<CharT>>
This facet is not present in the locale database so the conversion would
fail due to a missing locale facet. Using basic_string avoids using the
locale.
As a drive-by fixes several bugs in the ofstream.cons tests. These
tested ifstream instead of ofstream with an open mode.
Implements:
- LWG3130 [input.output] needs many addressof
Closes#100246.
Changes the loop range to match similar tests and avoids zero
iterations. The original motivation to reduce the number of iterations
was to allow the test to be executed during constant evaluation.
Fixes: https://github.com/llvm/llvm-project/issues/100502
This is in relation to mr #93350. It was merged to main, but reverted
because of failing sanitizer builds on PowerPC.
The fix includes replacing the hard-coded threshold constants (e.g.
`__overflow_threshold`) for different floating-point sizes by a general
computation using `std::ldexp`. Thus, it should now work for all architectures.
This has the drawback of not being `constexpr` anymore as `std::ldexp`
is not implemented as `constexpr` (even though the standard mandates it
for C++23).
Closes#92782
We were only checking that the comparator was rvalue callable,
when in reality the algorithms always call comparators as lvalues.
This patch also refactors the tests for callable requirements and
expands it to a few missing algorithms.
This is take 2 of #73451, which was reverted because it broke some
CI bots. The issue was that we checked __is_callable with arguments
in the wrong order inside std::upper_bound. This has now been fixed
and a test was added.
Fixes#69554
The tests kept being based on std::string instead of std::string_view to
allow testing with older C++ dialects.
Adds tests for:
- LWG3112 system_error and filesystem_error constructors taking a string
may not be able to meet their postconditions
Investigating #96612 shows our implementation was different from the
Standard and could cause UB. Testing the codegen showed quite a bit of
assembly generated for these functions. The functions have been written
differently which allows Clang to optimize the code to use simple CPU
rotate instructions.
Fixes: https://github.com/llvm/llvm-project/issues/96612
This reverts commit 8d151f804ff43aaed1edf810bb2a07607b8bba14, which
broke some build bots. I think that is caused by an invalid argument
order when checking __is_comparable in upper_bound.
We were only checking that the comparator was rvalue callable,
when in reality the algorithms always call comparators as lvalues.
This patch also refactors the tests for callable requirements and
expands it to a few missing algorithms.
Fixes#69554
As mentioned in the LWG issue libc++ has already implemented the
optimization. This adds tests and documents the implementation defined
behaviour.
Drive-by fixes an initialization.
This patch increases the alignment requirement for std::atomic_ref
such that we can guarantee lockfree operations more often. Specifically,
we require types that are 1, 2, 4, 8, or 16 bytes in size to be aligned
to at least their size to be used with std::atomic_ref.
This is the case for most types, however a notable exception is
`long long` on x86, which is 8 bytes in length but has an alignment
of 4.
As a result of this patch, one has to be more careful about the
alignment of objects used with std::atomic_ref. Failure to provide
a properly-aligned object to std::atomic_ref is a precondition
violation and is technically UB. On the flipside, this allows us
to provide an atomic_ref that is actually lockfree more often,
which is an important QOI property.
More information in the discussion at https://github.com/llvm/llvm-project/pull/99570#issuecomment-2237668661.
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
We were not declaring `__uses_allocator_construction_args` helper
functions, leading to several valid uses failing to compile. This
patch solves the problem by moving these helper functions into a
struct, which also reduces the amount of redundant SFINAE we need
to perform since most overloads are checking for a cv-qualfied pair.
Fixes#66714
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
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.
This is a follow up to https://github.com/llvm/llvm-project/pull/98717,
which made lock_guard available under _LIBCPP_HAS_NO_THREADS. We can
make unique_lock available under similar circumstances. This patch
follows the example in #98717, by:
- Removing the preprocessor guards for _LIBCPP_HAS_NO_THREADS in the
unique_lock header.
- providing a set of custom mutex implementations in a local header.
- using custom locks in tests that can be made to work under
`no-threads`.
This takes 1m40s to run when testing picolib on qemu. This isn't the end
of the world but that's on an AArch64 server. So if someone felt the
need to mark this unsupported in the first place, it's likely much
slower on average hardware.
This adds the new std::enable_nonlocking_formatter_optimization trait in
<format>. This trait will be used in std::print to implement the
performance benefits.
Implements parts of
- P3107R5 - Permit an efficient implementation of ``std::print``
In the tests I added for `ranges::find_last{_if{_not}}`, I accidentally
introduced an assumption that `same_as<array<T, 0>::iterator, T*>`; this
is a faulty assumption on MSVC-STL.
Fixes#100498.
The polymorphic_allocator was added in C++17.
This issue was filed in 2022 so well after C++20. This issue adds an
operator==.
Starting with C++20 this adds a compiler generated operator!=. To have
the same behaviour in C++17 and C++20 (and later) a manual operator!= is
defined in C++17.
Implements
- LWG3683 operator== for polymorphic_allocator cannot deduce template
argument in common cases
The builtin __atomic_always_lock_free takes into account the type of the
pointer provided as the second argument. Because we were passing void*,
rather than T*, the calculation failed. This meant that
atomic_ref<T>::is_always_lock_free was only true for char & bool.
This bug exists elsewhere in the atomic library (when using GCC, we fail
to pass a pointer at all, and we fail to correctly align the atomic like
_Atomic would).
This change also attempts to start sorting out testing difficulties with
this function that caused the bug to exist by using the
__GCC_ATOMIC_(CHAR|SHORT|INT|LONG|LLONG|POINTER)_IS_LOCK_FREE predefined
macros to establish an expected value for `is_always_lock_free` and
`is_lock_free` for the respective types, as well as types with matching
sizes and compatible alignment values.
Using these compiler pre-defines we can actually validate that certain
types, like char and int, are actually always lock free like they are on
every platform in the wild.
Note that this patch was actually authored by Eric Fiselier but I picked
up the patch and GitHub won't let me set Eric as the primary author.
Co-authored-by: Eric Fiselier <eric@efcs.ca>
This fixes testing with MinGW, if built without
__USE_MINGW_ANSI_STDIO=1.
On x86 MinGW, such a configuration fails printf tests with long doubles
due to mismatches between 80 and 64 bit long doubles - but on ARM,
there's no such issue, so building without __USE_MINGW_ANSI_STDIO=1 is
perfectly valid there.
Add another similar XFAIL to a libcxxabi test; this test isn't executed
in MSVC environments, so no XFAIL has been needed so far.
This speeds up the CI a bit (anecdotally ~10%) for those jobs, and it
also helps ensure that we are clean w.r.t. Clang modules when we disable
some of the carve-outs like no-localization or no-threads.
This PR is required to fix copy_file_large.pass.cpp which is failing on
z/OS in all ASCII variations. The problem is that a destination file is
opened in binary mode and auto-conversion does not happen when this lit
is compiled with -fzos-le-char-mode=ascii.
In addition opening a destination file will match a text mode of
`fopen()` of a source file.
This implements the requirements for the container iterator requirements
for array, deque, vector, and `vector<bool>`.
Implements:
- LWG3352 strong_equality isn't a thing
Implements parts of:
- P1614R2 The Mothership has Landed
Fixes: https://github.com/llvm/llvm-project/issues/62486