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