]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/MismatchedDeallocator-checker-test.mm
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
[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 //--------------- test new family
63 void testNew1() {
64   int *p = new int;
65   free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
66 }
67
68 void testNew2() {
69   int *p = (int *)operator new(0);
70   free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
71 }
72
73 void testNew3() {
74   int *p = new int[1];
75   free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
76 }
77
78 void testNew4() {
79   int *p = new int;
80   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
81 }
82
83 void testNew5() {
84   int *p = (int *)operator new(0);
85   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
86 }
87
88 void testNew6() {
89   int *p = new int[1];
90   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
91 }
92
93 void testNew7() {
94   int *p = new int;
95   delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
96 }
97
98 void testNew8() {
99   int *p = (int *)operator new(0);
100   delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
101 }
102
103 void testNew9() {
104   int *p = new int[1];
105   delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
106 }
107
108 void testNew10() {
109   int *p = (int *)operator new[](0);
110   delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
111 }
112
113 void testNew11(NSUInteger dataLength) {
114   int *p = new int;
115   NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not +dataWithBytesNoCopy:length:freeWhenDone:}}
116   // FIXME: should be "+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'."
117 }
118
119 //-------------------------------------------------------
120 // Check for intersection with unix.Malloc bounded with 
121 // unix.MismatchedDeallocator
122 //-------------------------------------------------------
123
124 // new/delete oparators are subjects of cplusplus.NewDelete.
125 void testNewDeleteNoWarn() {
126   int i;
127   delete &i; // no-warning
128
129   int *p1 = new int;
130   delete ++p1; // no-warning
131
132   int *p2 = new int;
133   delete p2;
134   delete p2; // no-warning
135
136   int *p3 = new int; // no-warning
137 }
138
139 void testDeleteOpAfterFree() {
140   int *p = (int *)malloc(sizeof(int));
141   free(p);
142   operator delete(p); // no-warning
143 }
144
145 void testDeleteAfterFree() {
146   int *p = (int *)malloc(sizeof(int));
147   free(p);
148   delete p; // no-warning
149 }
150
151 void testStandardPlacementNewAfterFree() {
152   int *p = (int *)malloc(sizeof(int));
153   free(p);
154   p = new(p) int; // no-warning
155 }
156
157 //---------------------------------------------------------------
158 // Check for intersection with cplusplus.NewDelete bounded with 
159 // unix.MismatchedDeallocator
160 //---------------------------------------------------------------
161
162 // malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
163 void testMallocFreeNoWarn() {
164   int i;
165   free(&i); // no-warning
166
167   int *p1 = (int *)malloc(sizeof(int));
168   free(++p1); // no-warning
169
170   int *p2 = (int *)malloc(sizeof(int));
171   free(p2);
172   free(p2); // no-warning
173
174   int *p3 = (int *)malloc(sizeof(int)); // no-warning
175 }
176
177 void testFreeAfterDelete() {
178   int *p = new int;  
179   delete p;
180   free(p); // no-warning
181 }
182
183 void testStandardPlacementNewAfterDelete() {
184   int *p = new int;  
185   delete p;
186   p = new(p) int; // no-warning
187 }
188
189
190 // Smart pointer example
191 template <typename T>
192 struct SimpleSmartPointer {
193   T *ptr;
194
195   explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
196   ~SimpleSmartPointer() {
197     delete ptr;
198     // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
199     // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
200   }
201 };
202
203 void testSimpleSmartPointerArrayNew() {
204   {
205     SimpleSmartPointer<int> a(new int);
206   } // no-warning
207
208   {
209     SimpleSmartPointer<int> a(new int[4]);
210   }
211 }
212
213 void testSimpleSmartPointerMalloc() {
214   {
215     SimpleSmartPointer<int> a(new int);
216   } // no-warning
217
218   {
219     SimpleSmartPointer<int> a((int *)malloc(4));
220   }
221 }