1 // RUN: %check_clang_tidy -std=c++98 %s modernize-use-nullptr %t -- -- -Wno-non-literal-null-conversion
2 //
3 // Some parts of the test (e.g. assignment of `const int` to `int *`) fail in
4 // C++11, so we need to run the test in C++98 mode.
5 //
6 // FIXME: Make the test work in all language modes.
7 
8 const unsigned int g_null = 0;
9 #define NULL 0
10 
test_assignment()11 void test_assignment() {
12   int *p1 = 0;
13   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr [modernize-use-nullptr]
14   // CHECK-FIXES: int *p1 = nullptr;
15   p1 = 0;
16   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
17   // CHECK-FIXES: p1 = nullptr;
18 
19   int *p2 = NULL;
20   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
21   // CHECK-FIXES: int *p2 = nullptr;
22 
23   p2 = p1;
24   // CHECK-FIXES: p2 = p1;
25 
26   const int null = 0;
27   int *p3 = null;
28   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
29   // CHECK-FIXES: int *p3 = nullptr;
30 
31   p3 = NULL;
32   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
33   // CHECK-FIXES: p3 = nullptr;
34 
35   int *p4 = p3;
36   // CHECK-FIXES: int *p4 = p3;
37 
38   p4 = null;
39   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
40   // CHECK-FIXES: p4 = nullptr;
41 
42   int i1 = 0;
43 
44   int i2 = NULL;
45 
46   int i3 = null;
47 
48   int *p5, *p6, *p7;
49   p5 = p6 = p7 = NULL;
50   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
51   // CHECK-FIXES: p5 = p6 = p7 = nullptr;
52 }
53 
54 struct Foo {
FooFoo55   Foo(int *p = NULL) : m_p1(p) {}
56   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
57   // CHECK-FIXES: Foo(int *p = nullptr) : m_p1(p) {}
58 
barFoo59   void bar(int *p = 0) {}
60   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use nullptr
61   // CHECK-FIXES: void bar(int *p = nullptr) {}
62 
bazFoo63   void baz(int i = 0) {}
64 
65   int *m_p1;
66   static int *m_p2;
67 };
68 
69 int *Foo::m_p2 = NULL;
70 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
71 // CHECK-FIXES: int *Foo::m_p2 = nullptr;
72 
73 template <typename T>
74 struct Bar {
BarBar75   Bar(T *p) : m_p(p) {
76     m_p = static_cast<T*>(NULL);
77     // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
78     // CHECK-FIXES: m_p = static_cast<T*>(nullptr);
79 
80     m_p = static_cast<T*>(reinterpret_cast<int*>((void*)NULL));
81     // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
82     // CHECK-FIXES: m_p = static_cast<T*>(nullptr);
83 
84     m_p = static_cast<T*>(p ? p : static_cast<void*>(g_null));
85     // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: use nullptr
86     // CHECK-FIXES: m_p = static_cast<T*>(p ? p : static_cast<void*>(nullptr));
87 
88     T *p2 = static_cast<T*>(reinterpret_cast<int*>((void*)NULL));
89     // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
90     // CHECK-FIXES: T *p2 = static_cast<T*>(nullptr);
91 
92     m_p = NULL;
93     // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
94     // CHECK-FIXES: m_p = nullptr;
95 
96     int i = static_cast<int>(0.f);
97     T *i2 = static_cast<int>(0.f);
98     // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
99     // CHECK-FIXES: T *i2 = nullptr;
100   }
101 
102   T *m_p;
103 };
104 
105 struct Baz {
BazBaz106   Baz() : i(0) {}
107   int i;
108 };
109 
test_cxx_cases()110 void test_cxx_cases() {
111   Foo f(g_null);
112   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
113   // CHECK-FIXES: Foo f(nullptr);
114 
115   f.bar(NULL);
116   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
117   // CHECK-FIXES: f.bar(nullptr);
118 
119   f.baz(g_null);
120 
121   f.m_p1 = 0;
122   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
123   // CHECK-FIXES: f.m_p1 = nullptr;
124 
125   Bar<int> b(g_null);
126   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
127   // CHECK-FIXES: Bar<int> b(nullptr);
128 
129   Baz b2;
130   int Baz::*memptr(0);
131   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr
132   // CHECK-FIXES: int Baz::*memptr(nullptr);
133 
134   memptr = 0;
135   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
136   // CHECK-FIXES: memptr = nullptr;
137 }
138 
139 void test_function_default_param1(void *p = 0);
140 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr
141 // CHECK-FIXES: void test_function_default_param1(void *p = nullptr);
142 
143 void test_function_default_param2(void *p = NULL);
144 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr
145 // CHECK-FIXES: void test_function_default_param2(void *p = nullptr);
146 
147 void test_function_default_param3(void *p = g_null);
148 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use nullptr
149 // CHECK-FIXES: void test_function_default_param3(void *p = nullptr);
150 
test_function(int * p)151 void test_function(int *p) {}
152 
test_function_no_ptr_param(int i)153 void test_function_no_ptr_param(int i) {}
154 
test_function_call()155 void test_function_call() {
156   test_function(0);
157   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
158   // CHECK-FIXES: test_function(nullptr);
159 
160   test_function(NULL);
161   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
162   // CHECK-FIXES: test_function(nullptr);
163 
164   test_function(g_null);
165   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
166   // CHECK-FIXES: test_function(nullptr);
167 
168   test_function_no_ptr_param(0);
169 }
170 
test_function_return1()171 char *test_function_return1() {
172   return 0;
173   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
174   // CHECK-FIXES: return nullptr;
175 }
176 
test_function_return2()177 void *test_function_return2() {
178   return NULL;
179   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
180   // CHECK-FIXES: return nullptr;
181 }
182 
test_function_return3()183 long *test_function_return3() {
184   return g_null;
185   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
186   // CHECK-FIXES: return nullptr;
187 }
188 
test_function_return4()189 int test_function_return4() {
190   return 0;
191 }
192 
test_function_return5()193 int test_function_return5() {
194   return NULL;
195 }
196 
test_function_return6()197 int test_function_return6() {
198   return g_null;
199 }
200 
test_function_return_cast1()201 int *test_function_return_cast1() {
202   return(int)0;
203   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
204   // CHECK-FIXES: return nullptr;
205 }
206 
test_function_return_cast2()207 int *test_function_return_cast2() {
208 #define RET return
209   RET(int)0;
210   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use nullptr
211   // CHECK-FIXES: RET nullptr;
212 #undef RET
213 }
214 
215 // Test parentheses expressions resulting in a nullptr.
test_parentheses_expression1()216 int *test_parentheses_expression1() {
217   return(0);
218   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
219   // CHECK-FIXES: return(nullptr);
220 }
221 
test_parentheses_expression2()222 int *test_parentheses_expression2() {
223   return(int(0.f));
224   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
225   // CHECK-FIXES: return(nullptr);
226 }
227 
test_nested_parentheses_expression()228 int *test_nested_parentheses_expression() {
229   return((((0))));
230   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
231   // CHECK-FIXES: return((((nullptr))));
232 }
233 
test_parentheses_explicit_cast()234 void *test_parentheses_explicit_cast() {
235   return(static_cast<void*>(0));
236   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
237   // CHECK-FIXES: return(static_cast<void*>(nullptr));
238 }
239 
test_parentheses_explicit_cast_sequence1()240 void *test_parentheses_explicit_cast_sequence1() {
241   return(static_cast<void*>(static_cast<int*>((void*)NULL)));
242   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
243   // CHECK-FIXES: return(static_cast<void*>(nullptr));
244 }
245 
test_parentheses_explicit_cast_sequence2()246 void *test_parentheses_explicit_cast_sequence2() {
247   return(static_cast<void*>(reinterpret_cast<int*>((float*)int(0.f))));
248   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
249   // CHECK-FIXES: return(static_cast<void*>(nullptr));
250 }
251 
252 // Test explicit cast expressions resulting in nullptr.
253 struct Bam {
BamBam254   Bam(int *a) {}
BamBam255   Bam(float *a) {}
operator =Bam256   Bam operator=(int *a) { return Bam(a); }
operator =Bam257   Bam operator=(float *a) { return Bam(a); }
258 };
259 
ambiguous_function(int * a)260 void ambiguous_function(int *a) {}
ambiguous_function(float * a)261 void ambiguous_function(float *a) {}
const_ambiguous_function(const int * p)262 void const_ambiguous_function(const int *p) {}
const_ambiguous_function(const float * p)263 void const_ambiguous_function(const float *p) {}
264 
test_explicit_cast_ambiguous1()265 void test_explicit_cast_ambiguous1() {
266   ambiguous_function((int*)0);
267   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use nullptr
268   // CHECK-FIXES: ambiguous_function((int*)nullptr);
269 }
270 
test_explicit_cast_ambiguous2()271 void test_explicit_cast_ambiguous2() {
272   ambiguous_function((int*)(0));
273   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use nullptr
274   // CHECK-FIXES: ambiguous_function((int*)nullptr);
275 }
276 
test_explicit_cast_ambiguous3()277 void test_explicit_cast_ambiguous3() {
278   ambiguous_function(static_cast<int*>(reinterpret_cast<int*>((float*)0)));
279   // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use nullptr
280   // CHECK-FIXES: ambiguous_function(static_cast<int*>(nullptr));
281 }
282 
test_explicit_cast_ambiguous4()283 Bam test_explicit_cast_ambiguous4() {
284   return(((int*)(0)));
285   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
286   // CHECK-FIXES: return(((int*)nullptr));
287 }
288 
test_explicit_cast_ambiguous5()289 void test_explicit_cast_ambiguous5() {
290   // Test for ambiguous overloaded constructors.
291   Bam k((int*)(0));
292   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use nullptr
293   // CHECK-FIXES: Bam k((int*)nullptr);
294 
295   // Test for ambiguous overloaded operators.
296   k = (int*)0;
297   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
298   // CHECK-FIXES: k = (int*)nullptr;
299 }
300 
test_const_pointers_abiguous()301 void test_const_pointers_abiguous() {
302   const_ambiguous_function((int*)0);
303   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use nullptr
304   // CHECK-FIXES: const_ambiguous_function((int*)nullptr);
305 }
306 
307 // Test where the implicit cast to null is surrounded by another implicit cast
308 // with possible explicit casts in-between.
test_const_pointers()309 void test_const_pointers() {
310   const int *const_p1 = 0;
311   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
312   // CHECK-FIXES: const int *const_p1 = nullptr;
313   const int *const_p2 = NULL;
314   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
315   // CHECK-FIXES: const int *const_p2 = nullptr;
316   const int *const_p3 = (int)0;
317   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
318   // CHECK-FIXES: const int *const_p3 = nullptr;
319   const int *const_p4 = (int)0.0f;
320   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
321   // CHECK-FIXES: const int *const_p4 = nullptr;
322   const int *const_p5 = (int*)0;
323   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use nullptr
324   // CHECK-FIXES: const int *const_p5 = (int*)nullptr;
325   int *t;
326   const int *const_p6 = static_cast<int*>(t ? t : static_cast<int*>(0));
327   // CHECK-MESSAGES: :[[@LINE-1]]:69: warning: use nullptr
328   // CHECK-FIXES: const int *const_p6 = static_cast<int*>(t ? t : static_cast<int*>(nullptr));
329 }
330 
test_nested_implicit_cast_expr()331 void test_nested_implicit_cast_expr() {
332   int func0(void*, void*);
333   int func1(int, void*, void*);
334 
335   (double)func1(0, 0, 0);
336   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr
337   // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: use nullptr
338   // CHECK-FIXES: (double)func1(0, nullptr, nullptr);
339   (double)func1(func0(0, 0), 0, 0);
340   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use nullptr
341   // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use nullptr
342   // CHECK-MESSAGES: :[[@LINE-3]]:30: warning: use nullptr
343   // CHECK-MESSAGES: :[[@LINE-4]]:33: warning: use nullptr
344   // CHECK-FIXES: (double)func1(func0(nullptr, nullptr), nullptr, nullptr);
345 }
346 
347 // FIXME: currently, the check doesn't work as it should with templates.
348 template<typename T>
349 class A {
350  public:
A(T * p=NULL)351   A(T *p = NULL) {}
352 
f()353   void f() {
354     Ptr = NULL;
355   }
356   T *Ptr;
357 };
358 
359 template<typename T>
f2(T * a=NULL)360 T *f2(T *a = NULL) {
361   return a ? a : NULL;
362 }
363