[libcxx-commits] [libcxx] dd9afdb - [libc++] Fix missing requires clause on variant operator<=>

Joe Loser via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 17 15:27:50 PDT 2022


Author: Joe Loser
Date: 2022-10-17T16:23:02-06:00
New Revision: dd9afdbb2ab47ad09e36c0afc94049285b474264

URL: https://github.com/llvm/llvm-project/commit/dd9afdbb2ab47ad09e36c0afc94049285b474264
DIFF: https://github.com/llvm/llvm-project/commit/dd9afdbb2ab47ad09e36c0afc94049285b474264.diff

LOG: [libc++] Fix missing requires clause on variant operator<=>

`std::variant::operator<=>` is missing a requires clause ensuring that
`operator<=>` only exists when all of the types in the variant are
`three_way_comparable`.

Add the missing requires clause and adjust the existing test which was
incorrect.

Fixes https://github.com/llvm/llvm-project/issues/58192.

Differential Revision: https://reviews.llvm.org/D136050

Added: 
    

Modified: 
    libcxx/include/variant
    libcxx/test/std/utilities/variant/variant.relops/three_way.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/variant b/libcxx/include/variant
index 147dadfde90f..26835f327da5 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -165,7 +165,7 @@ namespace std {
   template <class... Types>
   constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
 
-  template <class... Types>
+  template <class... Types> requires (three_way_comparable<Types> && ...)
   constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
     operator<=>(const variant<Types...>&, const variant<Types...>&);           // since C++20
 
@@ -1638,7 +1638,7 @@ constexpr bool operator==(const variant<_Types...>& __lhs,
 
 #  if _LIBCPP_STD_VER > 17
 
-template <class... _Types>
+template <class... _Types> requires (three_way_comparable<_Types> && ...)
 _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...>
 operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
   using __variant_detail::__visitation::__variant;

diff  --git a/libcxx/test/std/utilities/variant/variant.relops/three_way.pass.cpp b/libcxx/test/std/utilities/variant/variant.relops/three_way.pass.cpp
index f851c535e40a..c235967abcc9 100644
--- a/libcxx/test/std/utilities/variant/variant.relops/three_way.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.relops/three_way.pass.cpp
@@ -12,7 +12,7 @@
 
 // template <class... Types> class variant;
 
-// template<class... Types>
+// template <class... Types> requires (three_way_comparable<Types> && ...)
 //   constexpr std::common_comparison_category_t<
 //     std::compare_three_way_result_t<Types>...>
 //   operator<=>(const variant<Types...>& t, const variant<Types...>& u);
@@ -170,15 +170,11 @@ static_assert(!has_three_way_op<std::variant<int, HasSimpleOrdering>>);
 static_assert(!three_way_comparable<HasSimpleOrdering>);
 static_assert(!three_way_comparable<std::variant<int, HasSimpleOrdering>>);
 
-static_assert( has_three_way_op<HasOnlySpaceship>);
-static_assert( has_three_way_op<std::variant<int, HasOnlySpaceship>>);
+static_assert(has_three_way_op<HasOnlySpaceship>);
+static_assert(!has_three_way_op<std::variant<int, HasOnlySpaceship>>);
 
-// variants containing types with unavailable operator== still exist but will
-// generate a compilation error if their operator== is invoked, so the variant
-// type here participates when asked for operator== and operator<=> even though
-// it would actually fail.
 static_assert(!three_way_comparable<HasOnlySpaceship>);
-static_assert( three_way_comparable<std::variant<int, HasOnlySpaceship>>);
+static_assert(!three_way_comparable<std::variant<int, HasOnlySpaceship>>);
 
 static_assert( has_three_way_op<HasFullOrdering>);
 static_assert( has_three_way_op<std::variant<int, HasFullOrdering>>);


        


More information about the libcxx-commits mailing list