• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %check_clang_tidy %s modernize-use-nullptr %t -- \
2 // RUN:   -config="{CheckOptions: [{key: modernize-use-nullptr.NullMacros, value: 'MY_NULL,NULL'}]}"
3 
4 #define NULL 0
5 
6 namespace std {
7 
8 typedef decltype(nullptr) nullptr_t;
9 
10 } // namespace std
11 
12 // Just to make sure make_null() could have side effects.
13 void external();
14 
make_null()15 std::nullptr_t make_null() {
16   external();
17   return nullptr;
18 }
19 
func()20 void func() {
21   void *CallTest = make_null();
22 
23   int var = 1;
24   void *CommaTest = (var+=2, make_null());
25 
26   int *CastTest = static_cast<int*>(make_null());
27 }
28 
dummy(int *)29 void dummy(int*) {}
side_effect()30 void side_effect() {}
31 
32 #define MACRO_EXPANSION_HAS_NULL \
33   void foo() { \
34     dummy(0); \
35     dummy(NULL); \
36     side_effect(); \
37   }
38 
39 MACRO_EXPANSION_HAS_NULL;
40 #undef MACRO_EXPANSION_HAS_NULL
41 
42 
test_macro_expansion1()43 void test_macro_expansion1() {
44 #define MACRO_EXPANSION_HAS_NULL \
45   dummy(NULL); \
46   side_effect();
47 
48   MACRO_EXPANSION_HAS_NULL;
49 
50 #undef MACRO_EXPANSION_HAS_NULL
51 }
52 
53 // Test macro expansion with cast sequence, PR15572.
test_macro_expansion2()54 void test_macro_expansion2() {
55 #define MACRO_EXPANSION_HAS_NULL \
56   dummy((int*)0); \
57   side_effect();
58 
59   MACRO_EXPANSION_HAS_NULL;
60 
61 #undef MACRO_EXPANSION_HAS_NULL
62 }
63 
test_macro_expansion3()64 void test_macro_expansion3() {
65 #define MACRO_EXPANSION_HAS_NULL \
66   dummy(NULL); \
67   side_effect();
68 
69 #define OUTER_MACRO \
70   MACRO_EXPANSION_HAS_NULL; \
71   side_effect();
72 
73   OUTER_MACRO;
74 
75 #undef OUTER_MACRO
76 #undef MACRO_EXPANSION_HAS_NULL
77 }
78 
test_macro_expansion4()79 void test_macro_expansion4() {
80 #define MY_NULL NULL
81   int *p = MY_NULL;
82   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr [modernize-use-nullptr]
83   // CHECK-FIXES: int *p = nullptr;
84 #undef MY_NULL
85 }
86 
87 #define IS_EQ(x, y) if (x != y) return;
test_macro_args()88 void test_macro_args() {
89   int i = 0;
90   int *Ptr;
91 
92   IS_EQ(static_cast<int*>(0), Ptr);
93   // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
94   // CHECK-FIXES: IS_EQ(static_cast<int*>(nullptr), Ptr);
95 
96   IS_EQ(0, Ptr);    // literal
97   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
98   // CHECK-FIXES: IS_EQ(nullptr, Ptr);
99 
100   IS_EQ(NULL, Ptr); // macro
101   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
102   // CHECK-FIXES: IS_EQ(nullptr, Ptr);
103 
104   // These are ok since the null literal is not spelled within a macro.
105 #define myassert(x) if (!(x)) return;
106   myassert(0 == Ptr);
107   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
108   // CHECK-FIXES: myassert(nullptr == Ptr);
109 
110   myassert(NULL == Ptr);
111   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
112   // CHECK-FIXES: myassert(nullptr == Ptr);
113 
114   // These are bad as the null literal is buried in a macro.
115 #define BLAH(X) myassert(0 == (X));
116 #define BLAH2(X) myassert(NULL == (X));
117   BLAH(Ptr);
118   BLAH2(Ptr);
119 
120   // Same as above but testing extra macro expansion.
121 #define EXPECT_NULL(X) IS_EQ(0, X);
122 #define EXPECT_NULL2(X) IS_EQ(NULL, X);
123   EXPECT_NULL(Ptr);
124   EXPECT_NULL2(Ptr);
125 
126   // Almost the same as above but now null literal is not in a macro so ok
127   // to transform.
128 #define EQUALS_PTR(X) IS_EQ(X, Ptr);
129   EQUALS_PTR(0);
130   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
131   // CHECK-FIXES: EQUALS_PTR(nullptr);
132   EQUALS_PTR(NULL);
133   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
134   // CHECK-FIXES: EQUALS_PTR(nullptr);
135 
136   // Same as above but testing extra macro expansion.
137 #define EQUALS_PTR_I(X) EQUALS_PTR(X)
138   EQUALS_PTR_I(0);
139   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
140   // CHECK-FIXES: EQUALS_PTR_I(nullptr);
141   EQUALS_PTR_I(NULL);
142   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
143   // CHECK-FIXES: EQUALS_PTR_I(nullptr);
144 
145   // Ok since null literal not within macro. However, now testing macro
146   // used as arg to another macro.
147 #define decorate(EXPR) side_effect(); EXPR;
148   decorate(IS_EQ(NULL, Ptr));
149   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
150   // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));
151   decorate(IS_EQ(0, Ptr));
152   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
153   // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));
154 
155   // This macro causes a NullToPointer cast to happen where 0 is assigned to z
156   // but the 0 literal cannot be replaced because it is also used as an
157   // integer in the comparison.
158 #define INT_AND_PTR_USE(X) do { int *z = X; if (X == 4) break; } while(false)
159   INT_AND_PTR_USE(0);
160 
161   // Both uses of X in this case result in NullToPointer casts so replacement
162   // is possible.
163 #define PTR_AND_PTR_USE(X) do { int *z = X; if (X != z) break; } while(false)
164   PTR_AND_PTR_USE(0);
165   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
166   // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);
167   PTR_AND_PTR_USE(NULL);
168   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
169   // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);
170 
171 #define OPTIONAL_CODE(...) __VA_ARGS__
172 #define NOT_NULL dummy(0)
173 #define CALL(X) X
174   OPTIONAL_CODE(NOT_NULL);
175   CALL(NOT_NULL);
176 
177 #define ENTRY(X) {X}
178   struct A {
179     int *Ptr;
180   } a[2] = {ENTRY(0), {0}};
181   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
182   // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr
183   // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
184 #undef ENTRY
185 
186 #define assert1(expr) (expr) ? 0 : 1
187 #define assert2 assert1
188   int *p;
189   assert2(p == 0);
190   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
191   // CHECK-FIXES: assert2(p == nullptr);
192   assert2(p == NULL);
193   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
194   // CHECK-FIXES: assert2(p == nullptr);
195 #undef assert2
196 #undef assert1
197 
198 #define ASSERT_EQ(a, b) a == b
199 #define ASSERT_NULL(x) ASSERT_EQ(static_cast<void *>(NULL), x)
200   int *pp;
201   ASSERT_NULL(pp);
202   ASSERT_NULL(NULL);
203   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use nullptr
204   // CHECK-FIXES: ASSERT_NULL(nullptr);
205 #undef ASSERT_NULL
206 #undef ASSERT_EQ
207 }
208 
209 // One of the ancestor of the cast is a NestedNameSpecifierLoc.
210 class NoDef;
211 char function(NoDef *p);
212 #define F(x) (sizeof(function(x)) == 1)
213 template<class T, T t>
214 class C {};
215 C<bool, F(0)> c;
216 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
217 // CHECK-FIXES: C<bool, F(nullptr)> c;
218 #undef F
219 
220 // Test default argument expression.
221 struct D {
DD222   explicit D(void *t, int *c = NULL) {}
223   // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use nullptr
224   // CHECK-FIXES: explicit D(void *t, int *c = nullptr) {}
225 };
226 
test_default_argument()227 void test_default_argument() {
228   D(nullptr);
229 }
230 
231 // Test on two neighbour CXXDefaultArgExprs nodes.
232 typedef unsigned long long uint64;
233 struct ZZ {
ZZZZ234   explicit ZZ(uint64, const uint64* = NULL) {}
235 // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use nullptr
236 // CHECK-FIXES: explicit ZZ(uint64, const uint64* = nullptr) {}
operator boolZZ237   operator bool()  { return true; }
238 };
239 
Hash(uint64 seed=0)240 uint64 Hash(uint64 seed = 0) { return 0; }
241 
f()242 void f() {
243   bool a;
244   a = ZZ(Hash());
245 }
246 
247 // Test on ignoring substituted template types.
248 template<typename T>
249 class TemplateClass {
250  public:
TemplateClass(int a,T default_value=0)251   explicit TemplateClass(int a, T default_value = 0) {}
252 
h(T * default_value=0)253   void h(T *default_value = 0) {}
254 
f(int * p=0)255   void f(int* p = 0) {}
256 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
257 // CHECK-FIXES: void f(int* p = nullptr) {}
258 };
259 
IgnoreSubstTemplateType()260 void IgnoreSubstTemplateType() {
261   TemplateClass<int*> a(1);
262 }
263 
264 // Test on casting nullptr.
265 struct G {
GG266   explicit G(bool, const char * = NULL) {}
267   // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use nullptr
268   // CHECK-FIXES: explicit G(bool, const char * = nullptr) {}
269 };
270 bool g(const char*);
test_cast_nullptr()271 void test_cast_nullptr() {
272   G(g(nullptr));
273   G(g((nullptr)));
274   G(g(static_cast<char*>(nullptr)));
275   G(g(static_cast<const char*>(nullptr)));
276 }
277 
278 // Test on recognizing multiple NULLs.
279 class H {
280 public:
281   H(bool);
282 };
283 
284 #define T(expression) H(expression);
285 bool h(int *, int *, int * = nullptr);
test_multiple_nulls()286 void test_multiple_nulls() {
287   T(h(NULL, NULL));
288 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr
289 // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use nullptr
290 // CHECK-FIXES: T(h(nullptr, nullptr));
291   T(h(NULL, nullptr));
292 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr
293 // CHECK-FIXES: T(h(nullptr, nullptr));
294   T(h(nullptr, NULL));
295 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
296 // CHECK-FIXES: T(h(nullptr, nullptr));
297   T(h(nullptr, nullptr));
298   T(h(NULL, NULL, NULL));
299 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr
300 // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use nullptr
301 // CHECK-MESSAGES: :[[@LINE-3]]:19: warning: use nullptr
302 // CHECK-FIXES: T(h(nullptr, nullptr, nullptr));
303 }
304 #undef T
305