Skip to content

Commit 65a1efc

Browse files
authored
Fixed shared_ptr comparisons with nullptr_t when spaceship is unavailable. (#76781)
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.
1 parent 0804ef2 commit 65a1efc

File tree

3 files changed

+80
-9
lines changed

3 files changed

+80
-9
lines changed

libcxx/include/__memory/shared_ptr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,12 +1166,12 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const shared_ptr<_Tp>& _
11661166

11671167
template <class _Tp>
11681168
inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
1169-
return less<_Tp*>()(__x.get(), nullptr);
1169+
return less<typename shared_ptr<_Tp>::element_type*>()(__x.get(), nullptr);
11701170
}
11711171

11721172
template <class _Tp>
11731173
inline _LIBCPP_HIDE_FROM_ABI bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
1174-
return less<_Tp*>()(nullptr, __x.get());
1174+
return less<typename shared_ptr<_Tp>::element_type*>()(nullptr, __x.get());
11751175
}
11761176

11771177
template <class _Tp>

libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ int main(int, char**)
5151
AssertComparisonsAreNoexcept<nullptr_t, std::shared_ptr<int> >();
5252
AssertComparisonsReturnBool<std::shared_ptr<int>, nullptr_t>();
5353
AssertComparisonsReturnBool<nullptr_t, std::shared_ptr<int> >();
54-
#if TEST_STD_VER > 17
54+
#if TEST_STD_VER >= 20
5555
AssertOrderAreNoexcept<std::shared_ptr<int>>();
5656
AssertOrderReturn<std::strong_ordering, std::shared_ptr<int>>();
5757
#endif
@@ -67,7 +67,7 @@ int main(int, char**)
6767
assert(!(nullptr > p1));
6868
assert((p1 >= nullptr));
6969
assert(!(nullptr >= p1));
70-
#if TEST_STD_VER > 17
70+
#if TEST_STD_VER >= 20
7171
assert((nullptr <=> p1) == std::strong_ordering::less);
7272
assert((p1 <=> nullptr) == std::strong_ordering::greater);
7373
#endif
@@ -83,9 +83,44 @@ int main(int, char**)
8383
assert(!(nullptr > p2));
8484
assert((p2 >= nullptr));
8585
assert((nullptr >= p2));
86-
#if TEST_STD_VER > 17
86+
#if TEST_STD_VER >= 20
87+
assert((p2 <=> nullptr) == std::strong_ordering::equivalent);
8788
assert((nullptr <=> p2) == std::strong_ordering::equivalent);
8889
#endif
8990

91+
#if TEST_STD_VER >= 17
92+
const std::shared_ptr<int[]> p3(new int[1]);
93+
assert(!(p3 == nullptr));
94+
assert(!(nullptr == p3));
95+
assert(!(p3 < nullptr));
96+
assert((nullptr < p3));
97+
assert(!(p3 <= nullptr));
98+
assert((nullptr <= p3));
99+
assert((p3 > nullptr));
100+
assert(!(nullptr > p3));
101+
assert((p3 >= nullptr));
102+
assert(!(nullptr >= p3));
103+
# if TEST_STD_VER >= 20
104+
assert((p3 <=> nullptr) == std::strong_ordering::greater);
105+
assert((nullptr <=> p3) == std::strong_ordering::less);
106+
# endif
107+
108+
const std::shared_ptr<int[]> p4;
109+
assert((p4 == nullptr));
110+
assert((nullptr == p4));
111+
assert(!(p4 < nullptr));
112+
assert(!(nullptr < p4));
113+
assert((p4 <= nullptr));
114+
assert((nullptr <= p4));
115+
assert(!(p4 > nullptr));
116+
assert(!(nullptr > p4));
117+
assert((p4 >= nullptr));
118+
assert((nullptr >= p4));
119+
# if TEST_STD_VER >= 20
120+
assert((p4 <=> nullptr) == std::strong_ordering::equivalent);
121+
assert((nullptr <=> p4) == std::strong_ordering::equivalent);
122+
# endif
123+
#endif
124+
90125
return 0;
91126
}

libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ TEST_CONSTEXPR_CXX23 bool test() {
5252
AssertEqualityAreNoexcept<nullptr_t, std::unique_ptr<int> >();
5353
AssertComparisonsReturnBool<std::unique_ptr<int>, nullptr_t>();
5454
AssertComparisonsReturnBool<nullptr_t, std::unique_ptr<int> >();
55-
#if TEST_STD_VER > 17
55+
#if TEST_STD_VER >= 20
5656
AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>, nullptr_t>();
5757
AssertOrderReturn<std::strong_ordering, nullptr_t, std::unique_ptr<int>>();
5858
#endif
@@ -71,9 +71,9 @@ TEST_CONSTEXPR_CXX23 bool test() {
7171
assert(!(nullptr > p1));
7272
assert((p1 >= nullptr));
7373
assert(!(nullptr >= p1));
74-
#if TEST_STD_VER > 17
75-
assert((nullptr <=> p1) == std::strong_ordering::less);
74+
#if TEST_STD_VER >= 20
7675
assert((p1 <=> nullptr) == std::strong_ordering::greater);
76+
assert((nullptr <=> p1) == std::strong_ordering::less);
7777
#endif
7878
}
7979

@@ -88,10 +88,46 @@ TEST_CONSTEXPR_CXX23 bool test() {
8888
assert(!(nullptr > p2));
8989
assert((p2 >= nullptr));
9090
assert((nullptr >= p2));
91-
#if TEST_STD_VER > 17
91+
#if TEST_STD_VER >= 20
92+
assert((p2 <=> nullptr) == std::strong_ordering::equivalent);
9293
assert((nullptr <=> p2) == std::strong_ordering::equivalent);
9394
#endif
9495

96+
const std::unique_ptr<int[]> p3(new int[1]);
97+
assert(!(p3 == nullptr));
98+
assert(!(nullptr == p3));
99+
// A pointer to allocated storage and a nullptr can't be compared at compile-time
100+
if (!TEST_IS_CONSTANT_EVALUATED) {
101+
assert(!(p3 < nullptr));
102+
assert((nullptr < p3));
103+
assert(!(p3 <= nullptr));
104+
assert((nullptr <= p3));
105+
assert((p3 > nullptr));
106+
assert(!(nullptr > p3));
107+
assert((p3 >= nullptr));
108+
assert(!(nullptr >= p3));
109+
#if TEST_STD_VER >= 20
110+
assert((nullptr <=> p3) == std::strong_ordering::less);
111+
assert((p3 <=> nullptr) == std::strong_ordering::greater);
112+
#endif
113+
}
114+
115+
const std::unique_ptr<int[]> p4;
116+
assert((p4 == nullptr));
117+
assert((nullptr == p4));
118+
assert(!(p4 < nullptr));
119+
assert(!(nullptr < p4));
120+
assert((p4 <= nullptr));
121+
assert((nullptr <= p4));
122+
assert(!(p4 > nullptr));
123+
assert(!(nullptr > p4));
124+
assert((p4 >= nullptr));
125+
assert((nullptr >= p4));
126+
#if TEST_STD_VER >= 20
127+
assert((p4 <=> nullptr) == std::strong_ordering::equivalent);
128+
assert((nullptr <=> p4) == std::strong_ordering::equivalent);
129+
#endif
130+
95131
return true;
96132
}
97133

0 commit comments

Comments
 (0)