1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
3 #include "Inputs/system-header-simulator-objc.h"
4 #include "Inputs/system-header-simulator-cxx.h"
6 typedef __typeof__(sizeof(int)) 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);
14 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
16 //---------------------------------------------------------------
17 // Test if an allocation function matches deallocation function
18 //---------------------------------------------------------------
20 //--------------- test malloc family
22 int *p = (int *)malloc(sizeof(int));
23 delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
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'}}
33 int *p = (int *)calloc(1, sizeof(int));
34 delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}}
37 void testMalloc4(const char *s) {
39 delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}}
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'}}
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}}
53 int *p = (int *)malloc(sizeof(int));
54 delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}}
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[]}}
63 int *p = (int *)__builtin_alloca(sizeof(int));
64 delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
67 //--------------- test new family
70 free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
74 int *p = (int *)operator new(0);
75 free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
80 free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
85 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
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()}}
95 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
103 delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
107 int *p = (int *)operator new(0);
108 delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
111 int *allocIntArray(unsigned c) {
116 int *p = allocIntArray(1);
117 delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
121 int *p = (int *)operator new[](0);
122 delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
125 void testNew11(NSUInteger dataLength) {
127 NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}}
130 //-------------------------------------------------------
131 // Check for intersection with unix.Malloc bounded with
132 // unix.MismatchedDeallocator
133 //-------------------------------------------------------
135 // new/delete oparators are subjects of cplusplus.NewDelete.
136 void testNewDeleteNoWarn() {
138 delete &i; // no-warning
141 delete ++p1; // no-warning
145 delete p2; // no-warning
147 int *p3 = new int; // no-warning
150 void testDeleteOpAfterFree() {
151 int *p = (int *)malloc(sizeof(int));
153 operator delete(p); // no-warning
156 void testDeleteAfterFree() {
157 int *p = (int *)malloc(sizeof(int));
159 delete p; // no-warning
162 void testStandardPlacementNewAfterFree() {
163 int *p = (int *)malloc(sizeof(int));
165 p = new(p) int; // no-warning
168 //---------------------------------------------------------------
169 // Check for intersection with cplusplus.NewDelete bounded with
170 // unix.MismatchedDeallocator
171 //---------------------------------------------------------------
173 // malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
174 void testMallocFreeNoWarn() {
176 free(&i); // no-warning
178 int *p1 = (int *)malloc(sizeof(int));
179 free(++p1); // no-warning
181 int *p2 = (int *)malloc(sizeof(int));
183 free(p2); // no-warning
185 int *p3 = (int *)malloc(sizeof(int)); // no-warning
188 void testFreeAfterDelete() {
191 free(p); // no-warning
194 void testStandardPlacementNewAfterDelete() {
197 p = new(p) int; // no-warning
201 // Smart pointer example
202 template <typename T>
203 struct SimpleSmartPointer {
206 explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
207 ~SimpleSmartPointer() {
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'}}
214 void testSimpleSmartPointerArrayNew() {
216 SimpleSmartPointer<int> a(new int);
220 SimpleSmartPointer<int> a(new int[4]);
224 void testSimpleSmartPointerMalloc() {
226 SimpleSmartPointer<int> a(new int);
230 SimpleSmartPointer<int> a((int *)malloc(4));