xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp (revision 01c11569fc67b2a00403f64695fff6d2b4e78fe5)
1*01c11569SPiotr Zegar // RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t -- -- -DGCC
2*01c11569SPiotr Zegar // RUN: %check_clang_tidy -std=c++20 %s modernize-use-nullptr %t -- -- -DCLANG
389a1d03eSRichard 
489a1d03eSRichard namespace std {
5db335d02SJens Massberg class strong_ordering;
6db335d02SJens Massberg 
7db335d02SJens Massberg // Mock how STD defined unspecified parameters for the operators below.
8*01c11569SPiotr Zegar #ifdef CLANG
9db335d02SJens Massberg struct _CmpUnspecifiedParam {
10db335d02SJens Massberg   consteval
_CmpUnspecifiedParamstd::_CmpUnspecifiedParam11db335d02SJens Massberg   _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {}
12db335d02SJens Massberg };
13db335d02SJens Massberg 
14*01c11569SPiotr Zegar #define UNSPECIFIED_TYPE _CmpUnspecifiedParam
15*01c11569SPiotr Zegar #endif
16*01c11569SPiotr Zegar 
17*01c11569SPiotr Zegar #ifdef GCC
18*01c11569SPiotr Zegar namespace __cmp_cat {
19*01c11569SPiotr Zegar   struct __unspec {
__unspecstd::__cmp_cat::__unspec20*01c11569SPiotr Zegar     constexpr __unspec(__unspec*) noexcept { }
21*01c11569SPiotr Zegar   };
22*01c11569SPiotr Zegar }
23*01c11569SPiotr Zegar 
24*01c11569SPiotr Zegar #define UNSPECIFIED_TYPE __cmp_cat::__unspec
25*01c11569SPiotr Zegar #endif
26*01c11569SPiotr Zegar 
2789a1d03eSRichard struct strong_ordering {
28db335d02SJens Massberg   signed char value;
29db335d02SJens Massberg 
operator ==(strong_ordering v,UNSPECIFIED_TYPE)30db335d02SJens Massberg   friend constexpr bool operator==(strong_ordering v,
31*01c11569SPiotr Zegar                                    UNSPECIFIED_TYPE) noexcept {
32db335d02SJens Massberg     return v.value == 0;
33db335d02SJens Massberg   }
operator <(strong_ordering v,UNSPECIFIED_TYPE)34db335d02SJens Massberg   friend constexpr bool operator<(strong_ordering v,
35*01c11569SPiotr Zegar                                   UNSPECIFIED_TYPE) noexcept {
36db335d02SJens Massberg     return v.value < 0;
37db335d02SJens Massberg   }
operator >(strong_ordering v,UNSPECIFIED_TYPE)38db335d02SJens Massberg   friend constexpr bool operator>(strong_ordering v,
39*01c11569SPiotr Zegar                                   UNSPECIFIED_TYPE) noexcept {
40db335d02SJens Massberg     return v.value > 0;
41db335d02SJens Massberg   }
operator >=(strong_ordering v,UNSPECIFIED_TYPE)42db335d02SJens Massberg   friend constexpr bool operator>=(strong_ordering v,
43*01c11569SPiotr Zegar                                    UNSPECIFIED_TYPE) noexcept {
44db335d02SJens Massberg     return v.value >= 0;
45db335d02SJens Massberg   }
4689a1d03eSRichard   static const strong_ordering equal, greater, less;
4789a1d03eSRichard };
48*01c11569SPiotr Zegar 
4989a1d03eSRichard constexpr strong_ordering strong_ordering::equal = {0};
5089a1d03eSRichard constexpr strong_ordering strong_ordering::greater = {1};
5189a1d03eSRichard constexpr strong_ordering strong_ordering::less = {-1};
5289a1d03eSRichard } // namespace std
5389a1d03eSRichard 
5489a1d03eSRichard class A {
55db335d02SJens Massberg   int a;
5689a1d03eSRichard public:
5789a1d03eSRichard   auto operator<=>(const A &other) const = default;
58db335d02SJens Massberg   // CHECK-FIXES: auto operator<=>(const A &other) const = default;
5989a1d03eSRichard };
6089a1d03eSRichard 
test_cxx_rewritten_binary_ops()6189a1d03eSRichard void test_cxx_rewritten_binary_ops() {
6289a1d03eSRichard   A a1, a2;
6389a1d03eSRichard   bool result;
6489a1d03eSRichard   // should not change next line to (a1 nullptr a2)
6589a1d03eSRichard   result = (a1 < a2);
6689a1d03eSRichard   // CHECK-FIXES: result = (a1 < a2);
6789a1d03eSRichard   // should not change next line to (a1 nullptr a2)
6889a1d03eSRichard   result = (a1 >= a2);
6989a1d03eSRichard   // CHECK-FIXES: result = (a1 >= a2);
7089a1d03eSRichard   int *ptr = 0;
7189a1d03eSRichard   // CHECK-FIXES: int *ptr = nullptr;
7289a1d03eSRichard   result = (a1 > (ptr == 0 ? a1 : a2));
7389a1d03eSRichard   // CHECK-FIXES: result = (a1 > (ptr == nullptr ? a1 : a2));
7489a1d03eSRichard   result = (a1 > ((a1 > (ptr == 0 ? a1 : a2)) ? a1 : a2));
7589a1d03eSRichard   // CHECK-FIXES: result = (a1 > ((a1 > (ptr == nullptr ? a1 : a2)) ? a1 : a2));
7689a1d03eSRichard }
77db335d02SJens Massberg 
testValidZero()78*01c11569SPiotr Zegar void testValidZero() {
79*01c11569SPiotr Zegar   A a1, a2;
80*01c11569SPiotr Zegar   auto result = a1 <=> a2;
81*01c11569SPiotr Zegar   if (result < 0) {}
82*01c11569SPiotr Zegar   // CHECK-FIXES: if (result < 0) {}
83*01c11569SPiotr Zegar }
84*01c11569SPiotr Zegar 
85db335d02SJens Massberg template<class T1, class T2>
86db335d02SJens Massberg struct P {
87db335d02SJens Massberg   T1 x1;
88db335d02SJens Massberg   T2 x2;
89db335d02SJens Massberg   friend auto operator<=>(const P&, const P&) = default;
90db335d02SJens Massberg   // CHECK-FIXES: friend auto operator<=>(const P&, const P&) = default;
91db335d02SJens Massberg };
92db335d02SJens Massberg 
foo(P<int,int> x,P<int,int> y)93db335d02SJens Massberg bool foo(P<int,int> x, P<int, int> y) { return x < y; }
94db335d02SJens Massberg // CHECK-FIXES: bool foo(P<int,int> x, P<int, int> y) { return x < y; }
95