[libcxx-commits] [libcxx] Fixed shared_ptr comparisons with nullptr_t when spaceship is unavailable. (PR #76781)

James Touton via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jan 8 10:16:14 PST 2024


https://github.com/Bekenn updated https://github.com/llvm/llvm-project/pull/76781

>From 0ee1d8f9ca4fb0ec4cf7d3d3bacf2667cb6e7afe Mon Sep 17 00:00:00 2001
From: James Touton <bekenn at gmail.com>
Date: Tue, 2 Jan 2024 21:30:05 -0800
Subject: [PATCH 1/3] Fixed shared_ptr comparisons with nullptr_t when
 spaceship is unavailable.

---
 libcxx/include/__memory/shared_ptr.h          |  4 +--
 .../cmp_nullptr.pass.cpp                      | 31 +++++++++++++++++
 .../unique.ptr.special/cmp_nullptr.pass.cpp   | 34 +++++++++++++++++++
 3 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 9aa938b2203121..9a73d439306d9e 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -1166,12 +1166,12 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const shared_ptr<_Tp>& _
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
-  return less<_Tp*>()(__x.get(), nullptr);
+  return less<typename shared_ptr<_Tp>::element_type*>()(__x.get(), nullptr);
 }
 
 template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
-  return less<_Tp*>()(nullptr, __x.get());
+  return less<typename shared_ptr<_Tp>::element_type*>()(nullptr, __x.get());
 }
 
 template <class _Tp>
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
index 3bc8ef3799ab66..5a131714fce4c4 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
@@ -87,5 +87,36 @@ int main(int, char**)
   assert((nullptr <=> p2) == std::strong_ordering::equivalent);
 #endif
 
+  const std::shared_ptr<int[]> p3(new int[1]);
+  assert(!(p3 == nullptr));
+  assert(!(nullptr == p3));
+  assert(!(p3 < nullptr));
+  assert((nullptr < p3));
+  assert(!(p3 <= nullptr));
+  assert((nullptr <= p3));
+  assert((p3 > nullptr));
+  assert(!(nullptr > p3));
+  assert((p3 >= nullptr));
+  assert(!(nullptr >= p3));
+#if TEST_STD_VER > 17
+  assert((nullptr <=> p3) == std::strong_ordering::less);
+  assert((p3 <=> nullptr) == std::strong_ordering::greater);
+#endif
+
+  const std::shared_ptr<int[]> p4;
+  assert((p4 == nullptr));
+  assert((nullptr == p4));
+  assert(!(p4 < nullptr));
+  assert(!(nullptr < p4));
+  assert((p4 <= nullptr));
+  assert((nullptr <= p4));
+  assert(!(p4 > nullptr));
+  assert(!(nullptr > p4));
+  assert((p4 >= nullptr));
+  assert((nullptr >= p4));
+#if TEST_STD_VER > 17
+  assert((nullptr <=> p4) == std::strong_ordering::equivalent);
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
index ddd02a455c5883..9ee88e22884488 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
@@ -92,6 +92,40 @@ TEST_CONSTEXPR_CXX23 bool test() {
   assert((nullptr <=> p2) == std::strong_ordering::equivalent);
 #endif
 
+  const std::unique_ptr<int[]> p3(new int[1]);
+  assert(!(p3 == nullptr));
+  assert(!(nullptr == p3));
+  // A pointer to allocated storage and a nullptr can't be compared at compile-time
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(!(p3 < nullptr));
+    assert((nullptr < p3));
+    assert(!(p3 <= nullptr));
+    assert((nullptr <= p3));
+    assert((p3 > nullptr));
+    assert(!(nullptr > p3));
+    assert((p3 >= nullptr));
+    assert(!(nullptr >= p3));
+#if TEST_STD_VER > 17
+    assert((nullptr <=> p3) == std::strong_ordering::less);
+    assert((p3 <=> nullptr) == std::strong_ordering::greater);
+#endif
+  }
+
+  const std::unique_ptr<int[]> p4;
+  assert((p4 == nullptr));
+  assert((nullptr == p4));
+  assert(!(p4 < nullptr));
+  assert(!(nullptr < p4));
+  assert((p4 <= nullptr));
+  assert((nullptr <= p4));
+  assert(!(p4 > nullptr));
+  assert(!(nullptr > p4));
+  assert((p4 >= nullptr));
+  assert((nullptr >= p4));
+#if TEST_STD_VER > 17
+  assert((nullptr <=> p4) == std::strong_ordering::equivalent);
+#endif
+
   return true;
 }
 

>From 5e6e73f93af14a62da8ad295635d1fefaaf5b5bc Mon Sep 17 00:00:00 2001
From: James Touton <bekenn at gmail.com>
Date: Wed, 3 Jan 2024 00:22:01 -0800
Subject: [PATCH 2/3] Don't test shared_ptr<T[]> in language modes earlier than
 C++17.

---
 .../util.smartptr.shared.cmp/cmp_nullptr.pass.cpp         | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
index 5a131714fce4c4..3281986a42c86b 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
@@ -87,6 +87,7 @@ int main(int, char**)
   assert((nullptr <=> p2) == std::strong_ordering::equivalent);
 #endif
 
+#if TEST_STD_VER > 14
   const std::shared_ptr<int[]> p3(new int[1]);
   assert(!(p3 == nullptr));
   assert(!(nullptr == p3));
@@ -98,10 +99,10 @@ int main(int, char**)
   assert(!(nullptr > p3));
   assert((p3 >= nullptr));
   assert(!(nullptr >= p3));
-#if TEST_STD_VER > 17
+#  if TEST_STD_VER > 17
   assert((nullptr <=> p3) == std::strong_ordering::less);
   assert((p3 <=> nullptr) == std::strong_ordering::greater);
-#endif
+#  endif
 
   const std::shared_ptr<int[]> p4;
   assert((p4 == nullptr));
@@ -114,8 +115,9 @@ int main(int, char**)
   assert(!(nullptr > p4));
   assert((p4 >= nullptr));
   assert((nullptr >= p4));
-#if TEST_STD_VER > 17
+#  if TEST_STD_VER > 17
   assert((nullptr <=> p4) == std::strong_ordering::equivalent);
+#  endif
 #endif
 
   return 0;

>From 66744b07aeeaccc77acaf8f2a711b9b0005a9989 Mon Sep 17 00:00:00 2001
From: James Touton <bekenn at gmail.com>
Date: Sun, 7 Jan 2024 13:46:11 -0800
Subject: [PATCH 3/3] PR feedback

---
 .../cmp_nullptr.pass.cpp                         | 16 +++++++++-------
 .../unique.ptr.special/cmp_nullptr.pass.cpp      | 14 ++++++++------
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
index 3281986a42c86b..4ca83ddff78e5b 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp
@@ -51,7 +51,7 @@ int main(int, char**)
   AssertComparisonsAreNoexcept<nullptr_t, std::shared_ptr<int> >();
   AssertComparisonsReturnBool<std::shared_ptr<int>, nullptr_t>();
   AssertComparisonsReturnBool<nullptr_t, std::shared_ptr<int> >();
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 20
   AssertOrderAreNoexcept<std::shared_ptr<int>>();
   AssertOrderReturn<std::strong_ordering, std::shared_ptr<int>>();
 #endif
@@ -67,7 +67,7 @@ int main(int, char**)
   assert(!(nullptr > p1));
   assert((p1 >= nullptr));
   assert(!(nullptr >= p1));
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 20
   assert((nullptr <=> p1) == std::strong_ordering::less);
   assert((p1 <=> nullptr) == std::strong_ordering::greater);
 #endif
@@ -83,11 +83,12 @@ int main(int, char**)
   assert(!(nullptr > p2));
   assert((p2 >= nullptr));
   assert((nullptr >= p2));
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 20
+  assert((p2 <=> nullptr) == std::strong_ordering::equivalent);
   assert((nullptr <=> p2) == std::strong_ordering::equivalent);
 #endif
 
-#if TEST_STD_VER > 14
+#if TEST_STD_VER >= 17
   const std::shared_ptr<int[]> p3(new int[1]);
   assert(!(p3 == nullptr));
   assert(!(nullptr == p3));
@@ -99,9 +100,9 @@ int main(int, char**)
   assert(!(nullptr > p3));
   assert((p3 >= nullptr));
   assert(!(nullptr >= p3));
-#  if TEST_STD_VER > 17
-  assert((nullptr <=> p3) == std::strong_ordering::less);
+#  if TEST_STD_VER >= 20
   assert((p3 <=> nullptr) == std::strong_ordering::greater);
+  assert((nullptr <=> p3) == std::strong_ordering::less);
 #  endif
 
   const std::shared_ptr<int[]> p4;
@@ -115,7 +116,8 @@ int main(int, char**)
   assert(!(nullptr > p4));
   assert((p4 >= nullptr));
   assert((nullptr >= p4));
-#  if TEST_STD_VER > 17
+#  if TEST_STD_VER >= 20
+  assert((p4 <=> nullptr) == std::strong_ordering::equivalent);
   assert((nullptr <=> p4) == std::strong_ordering::equivalent);
 #  endif
 #endif
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
index 9ee88e22884488..6f0ba2e756196c 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
@@ -52,7 +52,7 @@ TEST_CONSTEXPR_CXX23 bool test() {
     AssertEqualityAreNoexcept<nullptr_t, std::unique_ptr<int> >();
     AssertComparisonsReturnBool<std::unique_ptr<int>, nullptr_t>();
     AssertComparisonsReturnBool<nullptr_t, std::unique_ptr<int> >();
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 20
     AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>, nullptr_t>();
     AssertOrderReturn<std::strong_ordering, nullptr_t, std::unique_ptr<int>>();
 #endif
@@ -71,9 +71,9 @@ TEST_CONSTEXPR_CXX23 bool test() {
     assert(!(nullptr > p1));
     assert((p1 >= nullptr));
     assert(!(nullptr >= p1));
-#if TEST_STD_VER > 17
-    assert((nullptr <=> p1) == std::strong_ordering::less);
+#if TEST_STD_VER >= 20
     assert((p1 <=> nullptr) == std::strong_ordering::greater);
+    assert((nullptr <=> p1) == std::strong_ordering::less);
 #endif
   }
 
@@ -88,7 +88,8 @@ TEST_CONSTEXPR_CXX23 bool test() {
   assert(!(nullptr > p2));
   assert((p2 >= nullptr));
   assert((nullptr >= p2));
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 20
+  assert((p2 <=> nullptr) == std::strong_ordering::equivalent);
   assert((nullptr <=> p2) == std::strong_ordering::equivalent);
 #endif
 
@@ -105,7 +106,7 @@ TEST_CONSTEXPR_CXX23 bool test() {
     assert(!(nullptr > p3));
     assert((p3 >= nullptr));
     assert(!(nullptr >= p3));
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 20
     assert((nullptr <=> p3) == std::strong_ordering::less);
     assert((p3 <=> nullptr) == std::strong_ordering::greater);
 #endif
@@ -122,7 +123,8 @@ TEST_CONSTEXPR_CXX23 bool test() {
   assert(!(nullptr > p4));
   assert((p4 >= nullptr));
   assert((nullptr >= p4));
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 20
+  assert((p4 <=> nullptr) == std::strong_ordering::equivalent);
   assert((nullptr <=> p4) == std::strong_ordering::equivalent);
 #endif
 



More information about the libcxx-commits mailing list