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