1 // RUN: %check_clang_tidy %s readability-delete-null-pointer %t -- -- -fno-delayed-template-parsing
2 
3 #define NULL 0
4 
5 template <typename T>
6 struct Templ {
fooTempl7   void foo() {
8     // t1
9     if (mem) // t2
10       delete mem;
11     // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: 'if' statement is unnecessary;
12     // CHECK-FIXES: // t1
13     // CHECK-FIXES-NEXT: {{^    }}// t2
14     // CHECK-FIXES-NEXT: delete mem;
15   }
16   T mem;
17 };
18 
19 template <typename T>
20 struct TemplPtr {
fooTemplPtr21   void foo() {
22     // t3
23     if (mem) // t4
24       delete mem;
25     // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: 'if' statement is unnecessary;
26     // CHECK-FIXES: // t3
27     // CHECK-FIXES-NEXT: {{^    }}// t4
28     // CHECK-FIXES-NEXT: delete mem;
29   }
30   T *mem;
31 };
32 
instantiate()33 void instantiate() {
34   Templ<int *> ti2;
35   ti2.foo();
36   TemplPtr<int> ti3;
37   ti3.foo();
38 }
39 
40 template <typename T>
41 struct NeverInstantiated {
fooNeverInstantiated42   void foo() {
43     // t1
44     if (mem) // t2
45       delete mem;
46     // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: 'if' statement is unnecessary;
47     // CHECK-FIXES: // t1
48     // CHECK-FIXES-NEXT: {{^    }}// t2
49     // CHECK-FIXES-NEXT: delete mem;
50   }
51   T mem;
52 };
53 
54 template <typename T>
55 struct NeverInstantiatedPtr {
fooNeverInstantiatedPtr56   void foo() {
57     // t3
58     if (mem) // t4
59       delete mem;
60     // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: 'if' statement is unnecessary;
61     // CHECK-FIXES: // t3
62     // CHECK-FIXES-NEXT: {{^    }}// t4
63     // CHECK-FIXES-NEXT: delete mem;
64   }
65   T *mem;
66 };
67 
f()68 void f() {
69   int *ps = 0;
70   if (ps /**/) // #0
71     delete ps;
72   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer]
73 
74   // CHECK-FIXES: int *ps = 0;
75   // CHECK-FIXES-NEXT: {{^  }}// #0
76   // CHECK-FIXES-NEXT: delete ps;
77 
78   int *p = 0;
79 
80   // #1
81   if (p) { // #2
82     delete p;
83   } // #3
84   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer]
85 
86   // CHECK-FIXES: {{^  }}// #1
87   // CHECK-FIXES-NEXT: {{^  }}// #2
88   // CHECK-FIXES-NEXT: delete p;
89   // CHECK-FIXES-NEXT: {{^  }}// #3
90 
91   int *p2 = new int[3];
92   // #4
93   if (p2) // #5
94     delete[] p2;
95   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: 'if' statement is unnecessary;
96 
97   // CHECK-FIXES: // #4
98   // CHECK-FIXES-NEXT: {{^  }}// #5
99   // CHECK-FIXES-NEXT: delete[] p2;
100 
101   int *p3 = 0;
102   if (NULL != p3) {
103     // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
104     delete p3;
105   }
106   // CHECK-FIXES-NOT: if (NULL != p3) {
107   // CHECK-FIXES: delete p3;
108 
109   int *p4 = nullptr;
110   if (p4 != nullptr) {
111     // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
112     delete p4;
113   }
114   // CHECK-FIXES-NOT: if (p4 != nullptr) {
115   // CHECK-FIXES: delete p4;
116 
117   char *c;
118   if (c != 0) {
119     // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
120     delete c;
121   }
122   // CHECK-FIXES-NOT: if (c != 0) {
123   // CHECK-FIXES: delete c;
124 
125   char *c2;
126   if (c2) {
127     // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary;
128     // CHECK-FIXES: } else {
129     // CHECK-FIXES: c2 = c;
130     delete c2;
131   } else {
132     c2 = c;
133   }
134   struct A {
135     void foo() {
136       if (mp) // #6
137         delete mp;
138       // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer]
139       // CHECK-FIXES: {{^      }}// #6
140       // CHECK-FIXES-NEXT: delete mp;
141     }
142     int *mp;
143   };
144 }
145 
g()146 void g() {
147   int *p5, *p6;
148   if (p5)
149     delete p6;
150 
151   if (p5 && p6)
152     delete p5;
153 
154   if (p6) {
155     int x = 5;
156     delete p6;
157   }
158 }
159