xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp (revision db335d02a5e7d98c24f7006e42129856ba1cd695)
189a1d03eSRichard // RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t
289a1d03eSRichard 
389a1d03eSRichard namespace std {
4*db335d02SJens Massberg class strong_ordering;
5*db335d02SJens Massberg 
6*db335d02SJens Massberg // Mock how STD defined unspecified parameters for the operators below.
7*db335d02SJens Massberg struct _CmpUnspecifiedParam {
8*db335d02SJens Massberg   consteval
9*db335d02SJens Massberg   _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
10*db335d02SJens Massberg };
11*db335d02SJens Massberg 
1289a1d03eSRichard struct strong_ordering {
13*db335d02SJens Massberg   signed char value;
14*db335d02SJens Massberg 
15*db335d02SJens Massberg   friend constexpr bool operator==(strong_ordering v,
16*db335d02SJens Massberg                                    _CmpUnspecifiedParam) noexcept {
17*db335d02SJens Massberg     return v.value == 0;
18*db335d02SJens Massberg   }
19*db335d02SJens Massberg   friend constexpr bool operator<(strong_ordering v,
20*db335d02SJens Massberg                                   _CmpUnspecifiedParam) noexcept {
21*db335d02SJens Massberg     return v.value < 0;
22*db335d02SJens Massberg   }
23*db335d02SJens Massberg   friend constexpr bool operator>(strong_ordering v,
24*db335d02SJens Massberg                                   _CmpUnspecifiedParam) noexcept {
25*db335d02SJens Massberg     return v.value > 0;
26*db335d02SJens Massberg   }
27*db335d02SJens Massberg   friend constexpr bool operator>=(strong_ordering v,
28*db335d02SJens Massberg                                    _CmpUnspecifiedParam) noexcept {
29*db335d02SJens Massberg     return v.value >= 0;
30*db335d02SJens Massberg   }
3189a1d03eSRichard   static const strong_ordering equal, greater, less;
3289a1d03eSRichard };
3389a1d03eSRichard constexpr strong_ordering strong_ordering::equal = {0};
3489a1d03eSRichard constexpr strong_ordering strong_ordering::greater = {1};
3589a1d03eSRichard constexpr strong_ordering strong_ordering::less = {-1};
3689a1d03eSRichard } // namespace std
3789a1d03eSRichard 
3889a1d03eSRichard class A {
39*db335d02SJens Massberg   int a;
4089a1d03eSRichard public:
4189a1d03eSRichard   auto operator<=>(const A &other) const = default;
42*db335d02SJens Massberg   // CHECK-FIXES: auto operator<=>(const A &other) const = default;
4389a1d03eSRichard };
4489a1d03eSRichard 
4589a1d03eSRichard void test_cxx_rewritten_binary_ops() {
4689a1d03eSRichard   A a1, a2;
4789a1d03eSRichard   bool result;
4889a1d03eSRichard   // should not change next line to (a1 nullptr a2)
4989a1d03eSRichard   result = (a1 < a2);
5089a1d03eSRichard   // CHECK-FIXES: result = (a1 < a2);
5189a1d03eSRichard   // should not change next line to (a1 nullptr a2)
5289a1d03eSRichard   result = (a1 >= a2);
5389a1d03eSRichard   // CHECK-FIXES: result = (a1 >= a2);
5489a1d03eSRichard   int *ptr = 0;
5589a1d03eSRichard   // CHECK-FIXES: int *ptr = nullptr;
5689a1d03eSRichard   result = (a1 > (ptr == 0 ? a1 : a2));
5789a1d03eSRichard   // CHECK-FIXES: result = (a1 > (ptr == nullptr ? a1 : a2));
5889a1d03eSRichard   result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2));
5989a1d03eSRichard   // CHECK-FIXES: result = (a1 > ((a1 > (ptr == nullptr ? a1 : a2)) ? a1 : a2));
6089a1d03eSRichard }
61*db335d02SJens Massberg 
62*db335d02SJens Massberg template<class T1, class T2>
63*db335d02SJens Massberg struct P {
64*db335d02SJens Massberg   T1 x1;
65*db335d02SJens Massberg   T2 x2;
66*db335d02SJens Massberg   friend auto operator<=>(const P&, const P&) = default;
67*db335d02SJens Massberg   // CHECK-FIXES: friend auto operator<=>(const P&, const P&) = default;
68*db335d02SJens Massberg };
69*db335d02SJens Massberg 
70*db335d02SJens Massberg bool foo(P<int,int> x, P<int, int> y) { return x < y; }
71*db335d02SJens Massberg // CHECK-FIXES: bool foo(P<int,int> x, P<int, int> y) { return x < y; }
72