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
As of now containers key_eq might get called when rehashing happens, which is redundant for unique keys containers.
Reviewed By: #libc, philnik, Mordante
Differential Revision: https://reviews.llvm.org/D128021
The debug mode has been broken pretty much ever since it was shipped
because it was possible to enable the debug mode in user code without
actually enabling it in the dylib, leading to ODR violations that
caused various kinds of failures.
This commit makes the debug mode a knob that is configured when
building the library and which can't be changed afterwards. This is
less flexible for users, however it will actually work as intended
and it will allow us, in the future, to add various kinds of checks
that do not assume the same ABI as the normal library. Furthermore,
this will make the debug mode more robust, which means that vendors
might be more tempted to support it properly, which hasn't been the
case with the current debug mode.
This patch shouldn't break any user code, except folks who are building
against a library that doesn't have the debug mode enabled and who try
to enable the debug mode in their code. Such users will get a compile-time
error explaining that this configuration isn't supported anymore.
In the future, we should further increase the granularity of the debug
mode checks so that we can cherry-pick which checks to enable, like we
do for unspecified behavior randomization.
Differential Revision: https://reviews.llvm.org/D122941
Instead of providing two different constructors for iterators that
support the debug mode, provide a single constructor but leave the
container parameter unused when the debug mode is not enabled.
This allows simplifying all the call sites to unconditionally pass
the container, which removes a bunch of duplication in the container's
implementation.
Note that this patch does add some complexity to std::span, however
that is only because std::span has the ability to use raw pointers
as iterators instead of __wrap_iter. In retrospect, I believe it was
a mistake to provide that capability, and so it will be removed in a
future patch, along with the complexity added by this patch.
Differential Revision: https://reviews.llvm.org/D126993
I audited all uses of _LIBCPP_ASSERT to make sure that we only used it
for "basic assertions", i.e. assertions with constant-time conditions.
I also audited all uses of _LIBCPP_DEBUG_ASSERT to make sure we used it
only for debug-mode assertions, and in one case had to change for
_LIBCPP_ASSERT instead.
As a fly-by, I also changed a couple of tests against nullptr or 0 to
be more explicit.
After this patch, all uses of _LIBCPP_ASSERT should be with constant-time
conditions, and all uses of _LIBCPP_DEBUG_ASSERT should be with conditions
that we only want to check when the debug mode is enabled.
Differential Revision: https://reviews.llvm.org/D122395
Notably the following ctors remain non-explicit because they
are used as implicit conversions in too many places:
* __debug_less(_Compare&)
* __map_iterator(_TreeIterator)
* __map_const_iterator(_TreeIterator)
* __hash_map_iterator(_HashIterator)
* __hash_map_const_iterator(_HashIterator)
Differential Revision: https://reviews.llvm.org/D119894
This commit reverts 5aaefa51 (and also partly 7f285f48e7 and b6d75682f9,
which were related to the original commit). As landed, 5aaefa51 had
unintended consequences on some downstream bots and didn't have proper
coverage upstream due to a few subtle things. Implementing this is
something we should do in libc++, however we'll first need to address
a few issues listed in https://reviews.llvm.org/D106124#3349710.
Differential Revision: https://reviews.llvm.org/D120683
libc++ has started splicing standard library headers into much more
fine-grained content for maintainability. It's very likely that outdated
and naive tooling (some of which is outside of LLVM's scope) will
suggest users include things such as <__ranges/access.h> instead of
<ranges>, and Hyrum's law suggests that users will eventually begin to
rely on this without the help of tooling. As such, this commit
intends to protect users from themselves, by making it a hard error for
anyone outside of the standard library to include libc++ detail headers.
Differential Revision: https://reviews.llvm.org/D106124
This is the first step towards disentangling the debug mode and assertions
in libc++. This patch doesn't make any functional change: it simply moves
_LIBCPP_ASSERT-related stuff to its own file so as to make it clear that
libc++ assertions and the debug mode are different things. Future patches
will make it possible to enable assertions without enabling the debug
mode.
Differential Revision: https://reviews.llvm.org/D119769
This addresses the usage of `operator&` in `<unordered_map>`.
(Note there are still more headers with the same issue.)
Reviewed By: #libc, Quuxplusone, ldionne
Differential Revision: https://reviews.llvm.org/D117393
This addresses the usage of `operator&` in `<unordered_map>`.
(Note there are still more headers with the same issue.)
Reviewed By: #libc, Quuxplusone, ldionne
Differential Revision: https://reviews.llvm.org/D117393
Fixes the tests added in D110852 for the debug iterators.
Similar issues with hijacking `operator&` still exist, they will be
addressed separately.
Reviewed By: #libc, ldionne, Quuxplusone
Differential Revision: https://reviews.llvm.org/D111564
Replace `&__rhs` with `_VSTD::addressof(__rhs)` to guard against ADL hijacking
of `operator&` in `operator=`. Thanks to @CaseyCarter for bringing it to our
attention.
Similar issues with hijacking `operator&` still exist, they will be
addressed separately.
Reviewed By: #libc, Quuxplusone, ldionne
Differential Revision: https://reviews.llvm.org/D110852
Detected by evil-izing the widely used `MoveOnly` testing type.
I had to patch some tests that were themselves using its comma operator,
but I think that's a worthwhile cost in order to catch more places
in our headers that needed comma-proofing.
The trick here is that even `++ptr, SomeClass()` can find a comma operator
by ADL, if `ptr` is of type `Evil*`. (A comma between two operands
of non-class-or-enum type is always treated as the built-in
comma, without ADL. But if either operand is class-or-enum, then
ADL happens for _both_ operands' types.)
Differential Revision: https://reviews.llvm.org/D109414
Add this attribute to some types to ensure that they have
debug info.
The debug info for these classes are required for debuggers to display
some STL types. With constructor homing (a new debug info optimization)
their debug info isn't emitted because their constructors are never
called.
The list of types with the attribute added are __hash_value_type,
__value_type, __tree_node_base, __tree_node, __hash_node, __list_node,
and __forward_list_node.
Differential Revision: https://reviews.llvm.org/D98750
Generally these calls aren't vulnerable to ADL because they involve only
primitive types. The ones in <list> and <vector> drag in namespace std
but that's OK; the ones in <fstream> and <strstream> are vulnerable
iff `CharT` is an enum type, which seems far-fetched.
But absolutely zero of them *need* ADL to happen; so in my opinion
they should all be consistently qualified, just like calls to any
other (non-user-customizable) functions in namespace std.
Also: Include <cstring> and <cwchar> in <__string>.
We seemed to be getting lucky that <memory> included <iterator>
included <iosfwd> included <wchar.h>. That gave us the
global-namespace `wmemmove`, but not `_VSTD::wmemmove`.
This is now fixed.
I didn't touch these headers:
<ext/__hash> uses strlen, safely
<support/ibm/locale_mgmt_aix.h> uses memcpy, safely
<string.h> uses memchr and strchr, safely
<wchar.h> uses wcschr, safely
<__bsd_locale_fallbacks.h> uses wcsnrtombs, safely
Differential Revision: https://reviews.llvm.org/D93061
I used a lot of `git grep` to find places where `std::` was being used
outside of comments and assert-messages. There were three outcomes:
- Qualified function calls, e.g. `std::move` becomes `_VSTD::move`.
This is the most common case.
- Typenames that don't need qualification, e.g. `std::allocator` becomes `allocator`.
Leaving these as `_VSTD::allocator` would also be fine, but I decided
that removing the qualification is more consistent with existing practice.
- Names that specifically need un-versioned `std::` qualification,
or that I wasn't sure about. For example, I didn't touch any code in
<atomic>, <math.h>, <new>, or any ext/ or experimental/ headers;
and I didn't touch any instances of `std::type_info`.
In some deduction guides, we were accidentally using `class Alloc = typename std::allocator<T>`,
despite `std::allocator<T>`'s type-ness not being template-dependent.
Because `std::allocator` is a qualified name, this did parse as we intended;
but what we meant was simply `class Alloc = allocator<T>`.
Differential Revision: https://reviews.llvm.org/D92250
This reverts commit 620adacf87.
Fix: unsupport C++03 for the new test, define helpers before __swap_allocator
(1) Add _VSTD:: qualification to __swap_allocator.
(2) Add _VSTD:: qualification consistently to __to_address.
(3) Add some more missing _VSTD:: to <vector>, with a regression test.
This part is cleanup after d9a4f936d0.
Note that a vector whose allocator actually runs afoul of any of these ADL calls will
likely also run afoul of simple things like `v1 == v2` (which is also an ADL call).
But, still, libc++ should be consistent in qualifying function calls wherever possible.
Relevant blog post: https://quuxplusone.github.io/blog/2019/09/26/uglification-doesnt-stop-adl/
Differential Revision: https://reviews.llvm.org/D91708
(1) Add _VSTD:: qualification to __swap_allocator.
(2) Add _VSTD:: qualification consistently to __to_address.
(3) Add some more missing _VSTD:: to <vector>, with a regression test.
This part is cleanup after d9a4f936d0.
Note that a vector whose allocator actually runs afoul of any of these ADL calls will
likely also run afoul of simple things like `v1 == v2` (which is also an ADL call).
But, still, libc++ should be consistent in qualifying function calls wherever possible.
Relevant blog post: https://quuxplusone.github.io/blog/2019/09/26/uglification-doesnt-stop-adl/
Differential Revision: https://reviews.llvm.org/D91708
We don't support any compiler that doesn't support variadics and rvalue
references in C++03 mode, so these workarounds can be dropped. There's
still *a lot* of cruft related to these workarounds, but I try to tackle
a bit of it here and there.