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
8const unsigned int g_null = 0;
9#define NULL 0
10
11void 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
54struct Foo {
55 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
59 void bar(int *p = 0) {}
60 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use nullptr
61 // CHECK-FIXES: void bar(int *p = nullptr) {}
62
63 void baz(int i = 0) {}
64
65 int *m_p1;
66 static int *m_p2;
67};
68
69int *Foo::m_p2 = NULL;
70// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
71// CHECK-FIXES: int *Foo::m_p2 = nullptr;
72
73template <typename T>
74struct Bar {
75 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
105struct Baz {
106 Baz() : i(0) {}
107 int i;
108};
109
110void 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(i: 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
139void 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
143void 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
147void 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
151void test_function(int *p) {}
152
153void test_function_no_ptr_param(int i) {}
154
155void test_function_call() {
156 test_function(p: 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(i: 0);
169}
170
171char *test_function_return1() {
172 return 0;
173 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
174 // CHECK-FIXES: return nullptr;
175}
176
177void *test_function_return2() {
178 return NULL;
179 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
180 // CHECK-FIXES: return nullptr;
181}
182
183long *test_function_return3() {
184 return g_null;
185 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
186 // CHECK-FIXES: return nullptr;
187}
188
189int test_function_return4() {
190 return 0;
191}
192
193int test_function_return5() {
194 return NULL;
195}
196
197int test_function_return6() {
198 return g_null;
199}
200
201int *test_function_return_cast1() {
202 return(int)0;
203 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
204 // CHECK-FIXES: return nullptr;
205}
206
207int *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.
216int *test_parentheses_expression1() {
217 return(0);
218 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
219 // CHECK-FIXES: return(nullptr);
220}
221
222int *test_parentheses_expression2() {
223 return(int(0.f));
224 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
225 // CHECK-FIXES: return(nullptr);
226}
227
228int *test_nested_parentheses_expression() {
229 return((((0))));
230 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
231 // CHECK-FIXES: return((((nullptr))));
232}
233
234void *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
240void *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
246void *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.
253struct Bam {
254 Bam(int *a) {}
255 Bam(float *a) {}
256 Bam operator=(int *a) { return Bam(a); }
257 Bam operator=(float *a) { return Bam(a); }
258};
259
260void ambiguous_function(int *a) {}
261void ambiguous_function(float *a) {}
262void const_ambiguous_function(const int *p) {}
263void const_ambiguous_function(const float *p) {}
264
265void test_explicit_cast_ambiguous1() {
266 ambiguous_function(a: (int*)0);
267 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use nullptr
268 // CHECK-FIXES: ambiguous_function((int*)nullptr);
269}
270
271void test_explicit_cast_ambiguous2() {
272 ambiguous_function(a: (int*)(0));
273 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use nullptr
274 // CHECK-FIXES: ambiguous_function((int*)nullptr);
275}
276
277void test_explicit_cast_ambiguous3() {
278 ambiguous_function(a: 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
283Bam 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
289void 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
301void test_const_pointers_abiguous() {
302 const_ambiguous_function(p: (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.
309void 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
331void 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.
348template<typename T>
349class A {
350 public:
351 A(T *p = NULL) {}
352
353 void f() {
354 Ptr = NULL;
355 }
356 T *Ptr;
357};
358
359template<typename T>
360T *f2(T *a = NULL) {
361 return a ? a : NULL;
362}
363

source code of clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-basic.cpp