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

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 2 21:39:38 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: James Touton (Bekenn)

<details>
<summary>Changes</summary>

@<!-- -->ldionne

This was causing compilation errors when attempting to compare a `shared_ptr<T[]>` with `nullptr`, as `get()` returns `T*` rather than `T (*)[]`.  `unique_ptr` did not have this issue, but I've added tests to make sure.

---
Full diff: https://github.com/llvm/llvm-project/pull/76781.diff


3 Files Affected:

- (modified) libcxx/include/__memory/shared_ptr.h (+2-2) 
- (modified) libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp (+31) 
- (modified) libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp (+34) 


``````````diff
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;
 }
 

``````````

</details>


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


More information about the libcxx-commits mailing list