]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/MismatchedDeallocator-checker-test.mm
Vendor import of clang trunk r238337:
[FreeBSD/FreeBSD.git] / test / Analysis / MismatchedDeallocator-checker-test.mm
1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
2
3 #include "Inputs/system-header-simulator-objc.h"
4 #include "Inputs/system-header-simulator-cxx.h"
5
6 typedef __typeof__(sizeof(int)) size_t;
7 void *malloc(size_t);
8 void *realloc(void *ptr, size_t size);
9 void *calloc(size_t nmemb, size_t size);
10 char *strdup(const char *s);
11 void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
12
13 void free(void *);
14 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
15
16 //---------------------------------------------------------------
17 // Test if an allocation function matches deallocation function
18 //---------------------------------------------------------------
19
20 //--------------- test malloc family
21 void testMalloc1() {
22   int *p = (int *)malloc(sizeof(int));
23   delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
24 }
25
26 void testMalloc2() {
27   int *p = (int *)malloc(8);
28   int *q = (int *)realloc(p, 16);
29   delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}}
30 }
31
32 void testMalloc3() {
33   int *p = (int *)calloc(1, sizeof(int));
34   delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}}
35 }
36
37 void testMalloc4(const char *s) {
38   char *p = strdup(s);
39   delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}}
40 }
41
42 void testMalloc5() {
43   int *p = (int *)my_malloc(sizeof(int));
44   delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}}
45 }
46
47 void testMalloc6() {
48   int *p = (int *)malloc(sizeof(int));
49   operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}}
50 }
51
52 void testMalloc7() {
53   int *p = (int *)malloc(sizeof(int));
54   delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}}
55 }
56
57 void testMalloc8() {
58   int *p = (int *)malloc(sizeof(int));
59   operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}}
60 }
61
62 void testAlloca() {
63   int *p = (int *)__builtin_alloca(sizeof(int));
64   delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
65 }
66
67 //--------------- test new family
68 void testNew1() {
69   int *p = new int;
70   free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
71 }
72
73 void testNew2() {
74   int *p = (int *)operator new(0);
75   free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
76 }
77
78 void testNew3() {
79   int *p = new int[1];
80   free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
81 }
82
83 void testNew4() {
84   int *p = new int;
85   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
86 }
87
88 void testNew5() {
89   int *p = (int *)operator new(0);
90   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
91 }
92
93 void testNew6() {
94   int *p = new int[1];
95   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
96 }
97
98 int *allocInt() {
99   return new int;
100 }
101 void testNew7() {
102   int *p = allocInt();
103   delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
104 }
105
106 void testNew8() {
107   int *p = (int *)operator new(0);
108   delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
109 }
110
111 int *allocIntArray(unsigned c) {
112   return new int[c];
113 }
114
115 void testNew9() {
116   int *p = allocIntArray(1);
117   delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
118 }
119
120 void testNew10() {
121   int *p = (int *)operator new[](0);
122   delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
123 }
124
125 void testNew11(NSUInteger dataLength) {
126   int *p = new int;
127   NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}}
128 }
129
130 //-------------------------------------------------------
131 // Check for intersection with unix.Malloc bounded with 
132 // unix.MismatchedDeallocator
133 //-------------------------------------------------------
134
135 // new/delete oparators are subjects of cplusplus.NewDelete.
136 void testNewDeleteNoWarn() {
137   int i;
138   delete &i; // no-warning
139
140   int *p1 = new int;
141   delete ++p1; // no-warning
142
143   int *p2 = new int;
144   delete p2;
145   delete p2; // no-warning
146
147   int *p3 = new int; // no-warning
148 }
149
150 void testDeleteOpAfterFree() {
151   int *p = (int *)malloc(sizeof(int));
152   free(p);
153   operator delete(p); // no-warning
154 }
155
156 void testDeleteAfterFree() {
157   int *p = (int *)malloc(sizeof(int));
158   free(p);
159   delete p; // no-warning
160 }
161
162 void testStandardPlacementNewAfterFree() {
163   int *p = (int *)malloc(sizeof(int));
164   free(p);
165   p = new(p) int; // no-warning
166 }
167
168 //---------------------------------------------------------------
169 // Check for intersection with cplusplus.NewDelete bounded with 
170 // unix.MismatchedDeallocator
171 //---------------------------------------------------------------
172
173 // malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
174 void testMallocFreeNoWarn() {
175   int i;
176   free(&i); // no-warning
177
178   int *p1 = (int *)malloc(sizeof(int));
179   free(++p1); // no-warning
180
181   int *p2 = (int *)malloc(sizeof(int));
182   free(p2);
183   free(p2); // no-warning
184
185   int *p3 = (int *)malloc(sizeof(int)); // no-warning
186 }
187
188 void testFreeAfterDelete() {
189   int *p = new int;  
190   delete p;
191   free(p); // no-warning
192 }
193
194 void testStandardPlacementNewAfterDelete() {
195   int *p = new int;  
196   delete p;
197   p = new(p) int; // no-warning
198 }
199
200
201 // Smart pointer example
202 template <typename T>
203 struct SimpleSmartPointer {
204   T *ptr;
205
206   explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
207   ~SimpleSmartPointer() {
208     delete ptr;
209     // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
210     // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
211   }
212 };
213
214 void testSimpleSmartPointerArrayNew() {
215   {
216     SimpleSmartPointer<int> a(new int);
217   } // no-warning
218
219   {
220     SimpleSmartPointer<int> a(new int[4]);
221   }
222 }
223
224 void testSimpleSmartPointerMalloc() {
225   {
226     SimpleSmartPointer<int> a(new int);
227   } // no-warning
228
229   {
230     SimpleSmartPointer<int> a((int *)malloc(4));
231   }
232 }