1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
4 #include "Inputs/system-header-simulator-objc.h"
5 #include "Inputs/system-header-simulator-cxx.h"
7 typedef __typeof__(sizeof(int)) size_t;
9 void *realloc(void *ptr, size_t size);
10 void *calloc(size_t nmemb, size_t size);
11 char *strdup(const char *s);
12 void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
15 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
17 //---------------------------------------------------------------
18 // Test if an allocation function matches deallocation function
19 //---------------------------------------------------------------
21 //--------------- test malloc family
23 int *p = (int *)malloc(sizeof(int));
24 delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
28 int *p = (int *)malloc(8);
29 int *q = (int *)realloc(p, 16);
30 delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}}
34 int *p = (int *)calloc(1, sizeof(int));
35 delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}}
38 void testMalloc4(const char *s) {
40 delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}}
44 int *p = (int *)my_malloc(sizeof(int));
45 delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}}
49 int *p = (int *)malloc(sizeof(int));
50 operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}}
54 int *p = (int *)malloc(sizeof(int));
55 delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}}
59 int *p = (int *)malloc(sizeof(int));
60 operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}}
64 int *p = (int *)__builtin_alloca(sizeof(int));
65 delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
68 //--------------- test new family
71 free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
75 int *p = (int *)operator new(0);
76 free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
81 free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
86 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
90 int *p = (int *)operator new(0);
91 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
96 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
104 delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
108 int *p = (int *)operator new(0);
109 delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
112 int *allocIntArray(unsigned c) {
117 int *p = allocIntArray(1);
118 delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
122 int *p = (int *)operator new[](0);
123 delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
126 void testNew11(NSUInteger dataLength) {
128 NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}}
131 //-------------------------------------------------------
132 // Check for intersection with unix.Malloc bounded with
133 // unix.MismatchedDeallocator
134 //-------------------------------------------------------
136 // new/delete oparators are subjects of cplusplus.NewDelete.
137 void testNewDeleteNoWarn() {
139 delete &i; // no-warning
142 delete ++p1; // no-warning
146 delete p2; // no-warning
148 int *p3 = new int; // no-warning
151 void testDeleteOpAfterFree() {
152 int *p = (int *)malloc(sizeof(int));
154 operator delete(p); // no-warning
157 void testDeleteAfterFree() {
158 int *p = (int *)malloc(sizeof(int));
160 delete p; // no-warning
163 void testStandardPlacementNewAfterFree() {
164 int *p = (int *)malloc(sizeof(int));
166 p = new(p) int; // no-warning
169 //---------------------------------------------------------------
170 // Check for intersection with cplusplus.NewDelete bounded with
171 // unix.MismatchedDeallocator
172 //---------------------------------------------------------------
174 // malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
175 void testMallocFreeNoWarn() {
177 free(&i); // no-warning
179 int *p1 = (int *)malloc(sizeof(int));
180 free(++p1); // no-warning
182 int *p2 = (int *)malloc(sizeof(int));
184 free(p2); // no-warning
186 int *p3 = (int *)malloc(sizeof(int)); // no-warning
189 void testFreeAfterDelete() {
192 free(p); // no-warning
195 void testStandardPlacementNewAfterDelete() {
198 p = new(p) int; // no-warning
202 // Smart pointer example
203 template <typename T>
204 struct SimpleSmartPointer {
207 explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
208 ~SimpleSmartPointer() {
210 // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
211 // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
215 void testSimpleSmartPointerArrayNew() {
217 SimpleSmartPointer<int> a(new int);
221 SimpleSmartPointer<int> a(new int[4]);
225 void testSimpleSmartPointerMalloc() {
227 SimpleSmartPointer<int> a(new int);
231 SimpleSmartPointer<int> a((int *)malloc(4));