diff options
Diffstat (limited to 'libcxx')
32 files changed, 194 insertions, 135 deletions
diff --git a/libcxx/docs/Contributing.rst b/libcxx/docs/Contributing.rst index 6aaa707..ac85619 100644 --- a/libcxx/docs/Contributing.rst +++ b/libcxx/docs/Contributing.rst @@ -174,10 +174,11 @@ Pre-commit CI Introduction ------------ -Unlike most parts of the LLVM project, libc++ uses a pre-commit CI [#]_. This -CI is hosted on `Buildkite <https://buildkite.com/llvm-project/libcxx-ci>`__ and -the build results are visible in the review on GitHub. Please make sure -the CI is green before committing a patch. +Unlike most parts of the LLVM project, libc++ uses a pre-commit CI [#]_. Some of +this CI is hosted on `Buildkite <https://buildkite.com/llvm-project/libcxx-ci>`__, +but some has migrated to the LLVM CI infrastructure. The build results are +visible in the review on GitHub. Please make sure the CI is green before +committing a patch. The CI tests libc++ for all :ref:`supported platforms <SupportedPlatforms>`. The build is started for every commit added to a Pull Request. A complete CI @@ -246,21 +247,89 @@ Below is a short description of the most interesting CI builds [#]_: Infrastructure -------------- -All files of the CI infrastructure are in the directory ``libcxx/utils/ci``. -Note that quite a bit of this infrastructure is heavily Linux focused. This is -the platform used by most of libc++'s Buildkite runners and developers. +The files for the CI infrastructure are split between the llvm-project +and the llvm-zorg repositories. All files of the CI infrastructure in +the llvm-project are in the directory ``libcxx/utils/ci``. Note that +quite a bit of this infrastructure is heavily Linux focused. This is +the platform used by most of libc++'s Buildkite runners and +developers. -Dockerfile -~~~~~~~~~~ +Dockerfile/Container Images +~~~~~~~~~~~~~~~~~~~~~~~~~~~ Contains the Docker image for the Ubuntu CI. Because the same Docker image is used for the ``main`` and ``release`` branch, it should contain no hard-coded -versions. It contains the used versions of Clang, various clang-tools, +versions. It contains the used versions of Clang, various clang-tools, GCC, and CMake. .. note:: This image is pulled from Docker hub and not rebuild when changing the Dockerfile. +Updating the CI testing container images +---------------------------------------- + +The libcxx linux premerge testing can run on one of three sets of runner +groups. The three runner group names are "llvm-premerge-libcxx-runners", +"llvm-premerge-libcxx-release-runners" and "llvm-premerge-libcxx-next-runners". +Which runner set to use is controlled by the contents of +https://github.com/llvm/llvm-project/blob/main/.github/workflows/libcxx-build-and-test.yaml. +By default, it uses "llvm-premerge-libcxx-runners". To switch to one of the +other runner sets, just replace all uses of "llvm-premerge-libcxx-runners" in +the yaml file with the desired runner set. + +Which container image is used by these three runner sets is controlled +and set by the variable values in +https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf. +The table below shows the variable names and +the runner sets to which they correspond. To see their values, follow the +link above (to variables.tf in llvm-zorg). + ++------------------------------------+---------------------------+ +|Runner Set |Variable | ++====================================+===========================+ +|llvm-premerge-libcxx-runners |libcxx_runner_image | ++------------------------------------+---------------------------+ +|llvm-premerge-libcxx-release-runners|libcxx_release_runner_image| ++------------------------------------+---------------------------+ +|llvm-premerge-libcxx-next-runners |libcxx_next_runner_image | ++------------------------------------+---------------------------+ + + +When updating the container image you can either update just the +runner binary (the part the connects to Github), or you can update +everything (tools, etc.). Whether to update just the runner or to update +everything is controlled by the value of ``ACTIONS_BASE_IMAGE``, under +``actions-builder`` in ``libcxx/utils/ci/docker-compose.yml``. + +To update just the runner binary, change the value of ``ACTIONS_BASE_IMAGE`` +to be a modified version of one of the libcxx runner variable images from +https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf, +as follows: Find the libcxx runner image name you want to use from the +variables.tf file. The name will be something like +``ghcr.io/llvm/libcxx-linux-builder:<some-commit-SHA>``. Replace +``libcxx-linux-builder`` with ``libcxx-linux-builder-base``. Use this new image +name as the value you assign to ``ACTIONS_BASE_IMAGE``. + +To update the entire container image, set the value of ``ACTIONS_BASE_IMAGE`` +to ``builder-base``. If the value is already ``builder-base`` (there +have been no just-the-runner updates since the last complete update), then you +need to find the line containing ``RUN echo "Last forced update executed on`` +in ``libcxx/utils/ci/Dockerfile`` and update the date to be the current date. + +Once you have created and merged a PR with those changes, a new image +will be created, and a link to it can be found at +https://github.com/llvm/llvm-project/pkgs/container/libcxx-linux-builder, +where the actual image name should be +``ghcr.io/llvm/libcxx-linux-builder:<SHA-of-committed-change-from-PR>``. + +Lastly you need to create a PR in the llvm-zorg repository, +updating the the value of the appropriate libcxx runner variable in +the variables.tf file mentioned above to the name of your newly created +image (see above paragraph about finding the image name). Once that change +has been merged, an LLVM premerge maintainer (a Google employee) must use +terraform to apply the change to the running GKE cluster. + + run-buildbot-container ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index c622512..5460664 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -132,7 +132,7 @@ "`LWG4200 <https://wg21.link/LWG4200>`__","The ``operation_state`` concept can be simplified","2025-06 (Sofia)","","","" "`LWG4201 <https://wg21.link/LWG4201>`__","``with-await-transform::await_transform`` should not use a deduced return type","2025-06 (Sofia)","","","" "`LWG4217 <https://wg21.link/LWG4217>`__","Clarify ``mdspan`` layout mapping requirements for ``rank == 0``","2025-06 (Sofia)","","","" -"`LWG4222 <https://wg21.link/LWG4222>`__","``expected`` constructor from a single value missing a constraint","2025-06 (Sofia)","","","" +"`LWG4222 <https://wg21.link/LWG4222>`__","``expected`` constructor from a single value missing a constraint","2025-06 (Sofia)","|Complete|","22","" "`LWG4224 <https://wg21.link/LWG4224>`__","Philox engines should be freestanding","2025-06 (Sofia)","","","" "`LWG4227 <https://wg21.link/LWG4227>`__","Missing ``noexcept`` operator in [exec.when.all]","2025-06 (Sofia)","","","" "`LWG4231 <https://wg21.link/LWG4231>`__","``datapar::chunk<N>`` should use ``simd-size-type`` instead of ``size_t``","2025-06 (Sofia)","","","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 51444ec..c6b87a3 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -447,14 +447,12 @@ set(files __fwd/get.h __fwd/ios.h __fwd/istream.h - __fwd/map.h __fwd/mdspan.h __fwd/memory.h __fwd/memory_resource.h __fwd/ostream.h __fwd/pair.h __fwd/queue.h - __fwd/set.h __fwd/span.h __fwd/sstream.h __fwd/stack.h diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h index 0f446b8..38a3412 100644 --- a/libcxx/include/__expected/expected.h +++ b/libcxx/include/__expected/expected.h @@ -557,7 +557,8 @@ public: template <class _Up = _Tp> requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> && - is_constructible_v<_Tp, _Up> && !__is_std_unexpected<remove_cvref_t<_Up>>::value && + !is_same_v<remove_cvref_t<_Up>, unexpect_t> && is_constructible_v<_Tp, _Up> && + !__is_std_unexpected<remove_cvref_t<_Up>>::value && (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_expected<remove_cvref_t<_Up>>::value)) _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>) expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened diff --git a/libcxx/include/__fwd/map.h b/libcxx/include/__fwd/map.h deleted file mode 100644 index 940298d..0000000 --- a/libcxx/include/__fwd/map.h +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___FWD_MAP_H -#define _LIBCPP___FWD_MAP_H - -#include <__config> -#include <__fwd/functional.h> -#include <__fwd/memory.h> -#include <__fwd/pair.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > > -class map; - -template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > > -class multimap; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___FWD_MAP_H diff --git a/libcxx/include/__fwd/set.h b/libcxx/include/__fwd/set.h deleted file mode 100644 index d5ef8d5..0000000 --- a/libcxx/include/__fwd/set.h +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___FWD_SET_H -#define _LIBCPP___FWD_SET_H - -#include <__config> -#include <__fwd/functional.h> -#include <__fwd/memory.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> > -class set; - -template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> > -class multiset; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___FWD_SET_H diff --git a/libcxx/include/__tree b/libcxx/include/__tree index 6ca1a62..3dd5ae5 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -13,9 +13,7 @@ #include <__algorithm/min.h> #include <__assert> #include <__config> -#include <__fwd/map.h> #include <__fwd/pair.h> -#include <__fwd/set.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> @@ -686,16 +684,6 @@ private: friend class __tree; template <class, class, class> friend class __tree_const_iterator; - template <class> - friend class __map_iterator; - template <class, class, class, class> - friend class map; - template <class, class, class, class> - friend class multimap; - template <class, class, class> - friend class set; - template <class, class, class> - friend class multiset; }; template <class _Tp, class _NodePtr, class _DiffType> @@ -709,18 +697,15 @@ class __tree_const_iterator { __end_node_pointer __ptr_; public: - using iterator_category = bidirectional_iterator_tag; - using value_type = __get_node_value_type_t<_Tp>; - using difference_type = _DiffType; - using reference = const value_type&; - using pointer = __rebind_pointer_t<_NodePtr, const value_type>; + using iterator_category = bidirectional_iterator_tag; + using value_type = __get_node_value_type_t<_Tp>; + using difference_type = _DiffType; + using reference = const value_type&; + using pointer = __rebind_pointer_t<_NodePtr, const value_type>; + using __non_const_iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, __node_pointer, difference_type>; _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} -private: - typedef __tree_iterator<_Tp, __node_pointer, difference_type> __non_const_iterator; - -public: _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; } @@ -762,16 +747,6 @@ private: template <class, class, class> friend class __tree; - template <class, class, class, class> - friend class map; - template <class, class, class, class> - friend class multimap; - template <class, class, class> - friend class set; - template <class, class, class> - friend class multiset; - template <class> - friend class __map_const_iterator; }; template <class _Tp, class _Compare> @@ -1388,8 +1363,9 @@ __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=( if (__root()) __root()->__parent_ = __end_node(); } - __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(static_cast<__node_base_pointer>(__end_node()))); - __size_ = __t.size(); + __begin_node_ = + __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node(); + __size_ = __t.size(); return *this; } diff --git a/libcxx/include/map b/libcxx/include/map index 0a43bd0..9f98abe 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -582,7 +582,6 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 # include <__functional/binary_function.h> # include <__functional/is_transparent.h> # include <__functional/operations.h> -# include <__fwd/map.h> # include <__iterator/erase_if_container.h> # include <__iterator/iterator_traits.h> # include <__iterator/ranges_iterator_traits.h> @@ -692,12 +691,12 @@ public: # if _LIBCPP_STD_VER >= 14 template <typename _K2> _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const { - return __comp_(__x, __y.__get_value().first); + return __comp_(__x, __y.first); } template <typename _K2> _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const { - return __comp_(__x.__get_value().first, __y); + return __comp_(__x.first, __y); } # endif }; @@ -861,7 +860,10 @@ public: friend class __tree_const_iterator; }; -template <class _Key, class _Tp, class _Compare, class _Allocator> +template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > > +class multimap; + +template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > > class map { public: // types: diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index b07a153e..c431c0c 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1607,7 +1607,6 @@ module std [system] { } module map { - module fwd { header "__fwd/map.h" } header "map" export * export std.iterator.reverse_iterator @@ -1974,7 +1973,6 @@ module std [system] { } module set { - module fwd { header "__fwd/set.h" } header "set" export * export std.iterator.reverse_iterator diff --git a/libcxx/include/set b/libcxx/include/set index 342a529..c77345b 100644 --- a/libcxx/include/set +++ b/libcxx/include/set @@ -522,7 +522,6 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20 # include <__config> # include <__functional/is_transparent.h> # include <__functional/operations.h> -# include <__fwd/set.h> # include <__iterator/erase_if_container.h> # include <__iterator/iterator_traits.h> # include <__iterator/ranges_iterator_traits.h> @@ -570,7 +569,10 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Key, class _Compare, class _Allocator> +template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> > +class multiset; + +template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> > class set { public: // types: diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp index 320ef57..222799f 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp @@ -48,12 +48,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add(&fun, 0); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add(&fun, 0); } } diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp index bdd8089..3bde3ad 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp @@ -51,12 +51,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed); } } diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp index 2c9f898..805ca34 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp @@ -48,12 +48,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub(&fun, 0); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub(&fun, 0); } } diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp index 88c4275..37a4237 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp @@ -51,12 +51,12 @@ void pointer_to_incomplete_type() { void function_pointer() { { volatile std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed); } { std::atomic<void (*)(int)> fun; - // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Pointer to function isn't allowed}} std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed); } } diff --git a/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp b/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp index 2427525..5352100 100644 --- a/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp +++ b/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.verify.cpp @@ -25,9 +25,9 @@ int main(int, char**) { { std::map<int, int, std::less<int>, std::allocator<int>> s1; std::map<int, int, std::less<int>, test_allocator<int>> s2; - // expected-error-re@*:* {{static assertion failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Allocator::value_type must be same type as value_type}} s1 <=> s2; - // expected-error-re@*:* {{static assertion failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Allocator::value_type must be same type as value_type}} s2 <=> s1; } // Mismatching comparision functions diff --git a/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp index c7ba765..62491e2 100644 --- a/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp @@ -33,6 +33,10 @@ int main(int, char**) { typedef std::map<int, double, transparent_less_not_referenceable> M; assert(M().count(C2Int{5}) == 0); } + { + using M = std::map<int, double, transparent_less_nonempty>; + assert(M().count(C2Int{5}) == 0); + } return 0; } diff --git a/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp index 75724bd..57ce9339 100644 --- a/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp @@ -40,6 +40,13 @@ int main(int, char**) { P result = example.equal_range(C2Int{5}); assert(result.first == result.second); } + { + using M = std::map<int, double, transparent_less_nonempty>; + using P = std::pair<typename M::iterator, typename M::iterator>; + M example; + P result = example.equal_range(C2Int{5}); + assert(result.first == result.second); + } return 0; } diff --git a/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp index 9825d6c..3f09d56 100644 --- a/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp @@ -36,6 +36,11 @@ int main(int, char**) { M example; assert(example.find(C2Int{5}) == example.end()); } + { + using M = std::map<int, double, transparent_less_nonempty>; + M example; + assert(example.find(C2Int{5}) == example.end()); + } return 0; } diff --git a/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp index fe7fe38..308a2ed 100644 --- a/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp @@ -36,6 +36,11 @@ int main(int, char**) { M example; assert(example.lower_bound(C2Int{5}) == example.end()); } + { + using M = std::map<int, double, transparent_less_nonempty>; + M example; + assert(example.lower_bound(C2Int{5}) == example.end()); + } return 0; } diff --git a/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp index 525aa67..332b71a 100644 --- a/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp @@ -36,6 +36,11 @@ int main(int, char**) { M example; assert(example.upper_bound(C2Int{5}) == example.end()); } + { + using M = std::map<int, double, transparent_less_nonempty>; + M example; + assert(example.upper_bound(C2Int{5}) == example.end()); + } return 0; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp b/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp index 239ad0a..e70e47e 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.nonmember/compare.three_way.verify.cpp @@ -25,9 +25,9 @@ int main(int, char**) { { std::multimap<int, int, std::less<int>, std::allocator<int>> s1; std::multimap<int, int, std::less<int>, test_allocator<int>> s2; - // expected-error-re@*:* {{static assertion failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Allocator::value_type must be same type as value_type}} s1 <=> s2; - // expected-error-re@*:* {{static assertion failed due to requirement 'is_same<int, std::pair<const int, int>>::value'{{.*}}Allocator::value_type must be same type as value_type}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}Allocator::value_type must be same type as value_type}} s2 <=> s1; } // Mismatching comparision functions diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp index 233d1a1..36f0ac2 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp @@ -33,6 +33,10 @@ int main(int, char**) { typedef std::multimap<int, double, transparent_less_not_referenceable> M; assert(M().count(C2Int{5}) == 0); } + { + using M = std::multimap<int, double, transparent_less_nonempty>; + assert(M().count(C2Int{5}) == 0); + } return 0; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp index 0bead6c..a362c03 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp @@ -40,6 +40,13 @@ int main(int, char**) { P result = example.equal_range(C2Int{5}); assert(result.first == result.second); } + { + using M = std::multimap<int, double, transparent_less_nonempty>; + using P = std::pair<typename M::iterator, typename M::iterator>; + M example; + P result = example.equal_range(C2Int{5}); + assert(result.first == result.second); + } return 0; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp index 701d4e3..ccb0900 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp @@ -36,6 +36,11 @@ int main(int, char**) { M example; assert(example.find(C2Int{5}) == example.end()); } + { + using M = std::multimap<int, double, transparent_less_nonempty>; + M example; + assert(example.find(C2Int{5}) == example.end()); + } return 0; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp index 79f9948..4b48530 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp @@ -36,6 +36,11 @@ int main(int, char**) { M example; assert(example.lower_bound(C2Int{5}) == example.end()); } + { + using M = std::multimap<int, double, transparent_less_nonempty>; + M example; + assert(example.lower_bound(C2Int{5}) == example.end()); + } return 0; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp index 62f5241..f2ae945 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp @@ -36,6 +36,11 @@ int main(int, char**) { M example; assert(example.upper_bound(C2Int{5}) == example.end()); } + { + using M = std::multimap<int, double, transparent_less_nonempty>; + M example; + assert(example.upper_bound(C2Int{5}) == example.end()); + } return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.overview/nttp.verify.cpp b/libcxx/test/std/containers/sequences/array/array.overview/nttp.verify.cpp index f50febf..e268dd9 100644 --- a/libcxx/test/std/containers/sequences/array/array.overview/nttp.verify.cpp +++ b/libcxx/test/std/containers/sequences/array/array.overview/nttp.verify.cpp @@ -45,7 +45,7 @@ using E = test<NotALiteral, 1, std::array<NotALiteral, 1>{}>; // expected-error-re@*:* {{non-type template parameter has non-literal type 'std::array<NotALiteral, 1U{{L{0,2}.*}}>'}} using F = test<std::string, 2, std::array<std::string, 2>{}>; -// expected-error-re@*:* {{type 'std::array<{{(std::)?}}string, 2U{{L{0,2}.*}}>' {{(\(aka 'array<basic_string<char>, 2UL{0,2}>'\) )?}}of non-type template parameter is not a structural type}} +// expected-error-re@*:* {{type {{.+}} of non-type template parameter is not a structural type}} } // namespace test_full_type namespace test_ctad { @@ -77,5 +77,5 @@ using E = test<std::array<NotALiteral, 1>{}>; // expected-error@-1 {{non-type template parameter has non-literal type 'std::array<NotALiteral, 1>'}} using F = test<std::array<std::string, 2>{}>; -// expected-error@-1 {{type 'std::array<std::string, 2>' (aka 'array<basic_string<char>, 2>') of non-type template parameter is not a structural type}} +// expected-error-re@-1 {{type {{.+}} of non-type template parameter is not a structural type}} } // namespace test_auto diff --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/params.verify.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/params.verify.cpp index bc9b563..0e03161 100644 --- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/params.verify.cpp +++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/params.verify.cpp @@ -24,7 +24,7 @@ int main(int, char**) // expected-error-re@*:* {{static assertion failed due to requirement '1ULL == 0 || 1ULL < 1ULL'{{.*}}linear_congruential_engine invalid parameters}} std::linear_congruential_engine<T, 0, 1, 1> e3; std::linear_congruential_engine<T, 1, 0, 1> e4; - // expected-error-re@*:* {{static assertion failed due to requirement 'is_unsigned<int>::value'{{.*}}_UIntType must be unsigned type}} + // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}_UIntType must be unsigned type}} std::linear_congruential_engine<int, 0, 0, 0> e5; return 0; diff --git a/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor1.verify.cpp b/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor1.verify.cpp index 3c61c76..efa1316 100644 --- a/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor1.verify.cpp +++ b/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor1.verify.cpp @@ -31,7 +31,7 @@ int main(int, char**) auto const& c_init = init; PT p1{init}; // expected-error {{no matching constructor}} PT p2{c_init}; // expected-error {{no matching constructor}} - PT p3{std::move(init)}; // expected-error {{no matching constructor for initialization of 'PT' (aka 'packaged_task<A (int, char)>')}} + PT p3{std::move(init)}; // expected-error-re {{no matching constructor for initialization of 'PT' (aka {{.+}})}} - return 0; + return 0; } diff --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp index fa9f5a1..13c0da2 100644 --- a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp +++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp @@ -14,6 +14,7 @@ // Constraints: // - is_same_v<remove_cvref_t<U>, in_place_t> is false; and // - is_same_v<expected, remove_cvref_t<U>> is false; and +// - is_same_v<remove_cvref_t<U>, unexpect_t> is false; and // - remove_cvref_t<U> is not a specialization of unexpected; and // - is_constructible_v<T, U> is true. // @@ -46,6 +47,16 @@ static_assert(!std::is_constructible_v<std::expected<FromJustInplace, int>, std: // Note that result is true because it is covered by the constructors that take expected static_assert(std::is_constructible_v<std::expected<int, int>, std::expected<int, int>&>); +struct T { + explicit T(auto) {} +}; +struct E { + E(int) {} +}; + +// is_same_v<remove_cvref_t<U>, unexpect_t> is false; +static_assert(!std::is_constructible_v<std::expected<T, E>, std::unexpect_t>); + // remove_cvref_t<U> is a specialization of unexpected // Note that result is true because it is covered by the constructors that take unexpected static_assert(std::is_constructible_v<std::expected<int, int>, std::unexpected<int>&>); diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.pair/nttp.verify.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.pair/nttp.verify.cpp index 9a39c18..f440b95 100644 --- a/libcxx/test/std/utilities/utility/pairs/pairs.pair/nttp.verify.cpp +++ b/libcxx/test/std/utilities/utility/pairs/pairs.pair/nttp.verify.cpp @@ -74,7 +74,7 @@ using H = test<std::pair<NotALiteral, NotALiteral>{}>; // expected-error@-1 {{non-type template parameter has non-literal type 'std::pair<NotALiteral, NotALiteral>'}} using I = test<std::pair<std::string, std::string>{}>; -// expected-error-re@-1 {{type 'std::pair<{{(std::)?}}string, {{(std::)?}}string>'{{( \(aka 'std::pair<std::string, std::string>'\))?}} of non-type template parameter is not a structural type}} +// expected-error-re@*:* {{type {{.+}} of non-type template parameter is not a structural type}} } // namespace test_ctad namespace test_auto { @@ -95,5 +95,5 @@ using H = test<std::pair<NotALiteral, NotALiteral>{}>; // expected-error@-1 {{non-type template parameter has non-literal type 'std::pair<NotALiteral, NotALiteral>'}} using I = test<std::pair<std::string, std::string>{}>; -// expected-error@-1 {{type 'std::pair<std::string, std::string>' (aka 'pair<basic_string<char>, basic_string<char>>') of non-type template parameter is not a structural type}} +// expected-error-re@-1 {{type {{.+}} of non-type template parameter is not a structural type}} } // namespace test_auto diff --git a/libcxx/test/support/is_transparent.h b/libcxx/test/support/is_transparent.h index 700c894..4b2a458 100644 --- a/libcxx/test/support/is_transparent.h +++ b/libcxx/test/support/is_transparent.h @@ -36,6 +36,17 @@ struct transparent_less_not_referenceable using is_transparent = void () const &; // it's a type; a weird one, but a type }; +// Prevent regression when empty base class optimization is not suitable. +// See https://github.com/llvm/llvm-project/issues/152543. +struct transparent_less_nonempty { + template <class T, class U> + constexpr bool operator()(T&& t, U&& u) const { + return std::forward<T>(t) < std::forward<U>(u); + } + struct is_transparent { + } pad_; // making this comparator non-empty +}; + struct transparent_less_no_type { template <class T, class U> |