Rather than removing the escape hatches for trivially default
constructible allocator and bitset's const reference type in LLVM 24,
keep them around for another release since they have not been widely
deployed yet.
Implement [LWG 4144](https://cplusplus.github.io/LWG/issue4144) by
explicitly rejecting `unique_ptr<T, D>` when `T*` is not a valid type.
This adds a pointability check and tests reference and abominable
function types.
Fixes#118359
Allocators are only required to be explicitly convertible between
different types. `shared_ptr` currently requires implicit conversions,
however.
This is a regression introduced by #200401.
This implements [LWG3918](https://wg21.link/LWG3918), which guarantees
copy elision for rvalues in `std::uninitialized_move/_n`. It also
implements [LWG4452](https://wg21.link/LWG4452), a minor correction that
makes the helper added by LWG3918 constexpr.
This additionally fixes a bug in `std::uninitialized_move/_n` where they
could create and then access dangling references. The previous
implementation used the following lambda as an implementation detail:
```c++
[](auto&& __iter) -> decltype(auto) { return std::move(*__iter); }
```
When `__iter` is a prvalue, this creates a temporary object within the
lambda's body and `std::move` then returns a reference to that object.
The reference dangles as soon as control leaves the lambda. This
behavior was not permitted by the standard even before LWG3918.
The new implementation fixes the bug by using a helper,
`std::__deref_move(__iter)`, which returns `*__iter` directly when
`*__iter` is already an rvalue.
Resolves#118339.
Resolves#171416.
While these algorithms are conceptually related to other
`uninitialized_*` algorithms, they're likely only ever going to be used
by `shared_ptr`. `uninitialized_algorithms.h` itself is also getting
rather large, so it makes sense to split the multidimensional versions
into their own header.
Fixes#207417
Per C++17 [depr.temporary.buffer]/4, `get_temporary_buffer` is required
to return `{nullptr, 0}` when the size argument is zero or negative.
libc++ used to correctly handle this, but the refactoring in
94e7c0b051 got this wrong.
GCC generally warns on negative size due to `-Walloc-size-larger-than=`,
which is false positive due to incomplete control flow analysis. The
warning is coupled with optimizations, and this patch make tests
suppress it instead.
This has the benefit of consistent placement for these macros (outside
the namespace, not inside it). This, in turn, makes it more obvious that
the condition applies to the entire namespace scope. Compile times are
also reduced a bit, since the compiler doesn't have to open a namespace
just to close it again.
This is enforced with a clang-tidy check.
As a drive-by this also fixes a few macro comments.
https://github.com/llvm/llvm-project/pull/200401 caused various ways to
create a `shared_ptr` control block to reject any allocators which
required a complete type. This patch allows allocators to again require
a complete type.
The `shared_ptr` control blocks don't need to be ABI stable as long as
we rename them. This can be thought of as adding a new control block,
which we've done before, and simply never generating the old one again.
This is done via an ABI tag on the control blocks, allowing us to change
their contents in whichever way we want without needing to consider
their ABI. In this case specifically, `_LIBCPP_COMPRESSED_{PAIR,TRIPLE}`
is removed, simplifying the code.
clang-tidy currently doesn't run in the CI because CMake doesn't find
the appropriate `ClangConfig.cmake` anymore. This adds the path so
clang-tidy is built again and fixes most issues. Some things are
disabled for now to get most checks back. They will be re-enabled later.
Remarks:
- Tests also verify that `uninitialized_default_construct(_n)`
algorithms do not initialize trivially default-constructible elements
(`int` in these tests) to determined values during constant evaluation.
We always define either `_LIBCPP_HAS_C_ATOMIC_IMP` or
`_LIBCPP_HAS_GCC_ATOMIC_IMP`, so we can remove any special handling of
not having an `<atomic>` header.
This patch does a couple of things:
- inline aliases to `__enable_if_t`s, making it easier to understand
what's actually going on
- make the `enable_if`s dependent via a `class _Deleter = deleter_type`
instead of a `bool` and `__dependent_type`, reducing the number of
instantiated classes
- remove `__unique_ptr_deleter_sfinae`
We've already switched some algorithms to use `__in_out_result` instead
of `pair` as the return type. This updates the remaining appropriate
algorithms.
Fixes https://github.com/llvm/llvm-project/issues/196645
`__uninitialized_allocator_copy_impl` has an optimization that replaces
`allocator_traits::construct` with `std::copy` for raw pointer ranges
when the element type is trivially copy constructible and trivially copy
assignable.
The copy-assignment trait only checks whether assignment from `const T&`
is trivial. That is weaker than the expression used by `std::copy`,
which evaluates `*out = *in`. If overload resolution selects a different
non-trivial assignment operator for that expression, `std::copy` can
call that operator on uninitialized storage.
Check `is_trivially_assignable<_Out&, _In&>` instead. This matches the
assignment expression used by `std::copy`, preserves the optimized path
when that assignment is actually trivial, and avoids making non-const
raw pointer callers select the generic `allocator_traits::construct`
overload due to a qualification conversion.
Add a vector copy-constructor regression test with a type whose
defaulted copy assignment is trivial but whose templated assignment
operator is selected for non-const lvalue sources.
This patch introduces `_LIBCPP_{BEGIN/END}_EXPLICIT_ABI_ANNOTATIONS` and
marks everything within an
`_LIBCPP_{BEGIN,END}_UNVERSIONED_NAMESPACE_STD` (and any derivatives
like `_LIBCPP_{BEGIN,END}_NAMESPACE_STD`) implicitly by default. This
allows us to drop `_LIBCPP_HIDE_FROM_ABI` in most of the code base,
except for functions which shouldn't be `_LIBCPP_HIDE_FROM_ABI`.
This patch doesn't remove any `_LIBCPP_HIDE_FROM_ABI`s, since we have
over 13k of them in the code base. Actually dropping them will happen
over some time to avoid too many merge conflicts.
Previously, the allocated size might be a bit too small for certain
cases. This patch makes the size calculated with potentially larger
alignment of the whole control block.
This PR introduces a `std::__is_sufficiently_aligned` helper function that
can be used for the `atomic_ref` C++20 constructors while the public
C++26 `std::is_sufficiently_aligned` delegates to the new helper
function.
Fixes#179803
Assisted-by: Claude Code
Signed-off-by: mlevine55 <mlevine55@bloomberg.net>
This doesn't improve compile times currently, but it does make it clear
that we don't need the definition of `shared_ptr` or `unique_ptr` for
`{in,}out_ptr`. It also reduces compile times quite a bit if we ever use
these utilities in another header.
#175913 removed that `__builtin_assume_dereferenceable(ptr, 0)` implies
`ptr != nullptr`, which should allow us to use the builtin with LLVM 23.
This reverts commit 776c09c212.
`__builtin_assume_dereferenceable` currently implies that the pointer
given to it is non-null, even if the size is zero. This causes
miscompilations, since we consider [nullptr, nullptr) to be a valid
range.
Reverts llvm/llvm-project#167697
`std::align` is heavily used in memory allocators. When we attempted to
switch from libstdc++ to libc++, we observed a **50%** performance
regression in a database query bench: the issue is that `std::align` in
libc++ is not an inline function, which prevents the compiler from
performing inlining optimizations.
make `std::align` an inline function will run about 2x faster. See
[benchmark
result](https://quick-bench.com/q/wPTnt9JCGn2S-3bu5gY9YrEf6KU).
---------
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
This is technically ABI breaking, since `is_trivial` and
`is_trivially_default_constructible` now return different results.
However, I don't think that's a significant issue, since `allocator` is
almost always used in classes which own memory, making them non-trivial
anyways.
`[[nodiscard]]` should be applied to functions where discarding the
return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html
1. `hash<shared_ptr>`, `hash<unique_ptr>`, `std::integer_sequence<>`
etc.
2. Also implements fixes to
https://github.com/llvm/llvm-project/issues/169634 on the go (issues
discovered during current implementation)
---------
Co-authored-by: A. Jiang <de34@live.cn>
Co-authored-by: Hristo Hristov <zingam@outlook.com>
Applied `[[nodiscard]]` where relevant to smart pointers and related
functions.
- [x] - `std::unique_ptr`
- [x] - `std::shared_ptr`
- [x] - `std::weak_ptr`
See guidelines:
-
https://libcxx.llvm.org/CodingGuidelines.html#apply-nodiscard-where-relevant
- `[[nodiscard]]` should be applied to functions where discarding the
return value is most likely a correctness issue. For example a locking
constructor in unique_lock.
---------
Co-authored-by: Hristo Hristov <zingam@outlook.com>
...according to Coding Guidelines: `[[nodiscard]]` should be applied to
functions where discarding the return value is most likely a correctness
issue.
Changes to:
- [x] `inout_ptr()`
- [x] `out_ptr()`
At the time of impelentation the `[[nodiscard]]` policy has not been
established yet.
---------
Co-authored-by: Hristo Hristov <zingam@outlook.com>
The Trivial Relocation feature has been removed from the C++26 working
draft. Based on discussions in Kona, it is unlikely that the
"replaceable" type concept will come back in the C++29 time frame.
Since we don't have a use for the type trait in the library at the
moment, remove the code associated to it. If we end up needing something
like it in the future, we can always add it back.
`aligned_storage` has been deprecated and will most likely be removed in
a future version of C++. This patch removes some of its uses to avoid
having to work around its removal in the future.
When we implemented array cookie support for hardening std::unique_ptr,
the implementation was only done for the Itanium ABI. I did not
initially realize that ARM was using a different ABI for array cookies,
so unique_ptr should not have been hardened on ARM.
However, we were also incorrectly setting the ABI-detection macro: we
were pretending to be using a vanilla Itanium ABI when in reality the
(similar but different) ARM ABI was in use. As a result, unique_ptr was
using the wrong representation for array cookies on ARM, which
fortunately only mattered in the case of overaligned types.
This patch fixes that.
rdar://160852193