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[]}}
62 //--------------- test new family
65 free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
69 int *p = (int *)operator new(0);
70 free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
75 free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
80 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
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()}}
90 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
95 delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
99 int *p = (int *)operator new(0);
100 delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
105 delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
109 int *p = (int *)operator new[](0);
110 delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
113 void testNew11(NSUInteger dataLength) {
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'."
119 //-------------------------------------------------------
120 // Check for intersection with unix.Malloc bounded with
121 // unix.MismatchedDeallocator
122 //-------------------------------------------------------
124 // new/delete oparators are subjects of cplusplus.NewDelete.
125 void testNewDeleteNoWarn() {
127 delete &i; // no-warning
130 delete ++p1; // no-warning
134 delete p2; // no-warning
136 int *p3 = new int; // no-warning
139 void testDeleteOpAfterFree() {
140 int *p = (int *)malloc(sizeof(int));
142 operator delete(p); // no-warning
145 void testDeleteAfterFree() {
146 int *p = (int *)malloc(sizeof(int));
148 delete p; // no-warning
151 void testStandardPlacementNewAfterFree() {
152 int *p = (int *)malloc(sizeof(int));
154 p = new(p) int; // no-warning
157 //---------------------------------------------------------------
158 // Check for intersection with cplusplus.NewDelete bounded with
159 // unix.MismatchedDeallocator
160 //---------------------------------------------------------------
162 // malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
163 void testMallocFreeNoWarn() {
165 free(&i); // no-warning
167 int *p1 = (int *)malloc(sizeof(int));
168 free(++p1); // no-warning
170 int *p2 = (int *)malloc(sizeof(int));
172 free(p2); // no-warning
174 int *p3 = (int *)malloc(sizeof(int)); // no-warning
177 void testFreeAfterDelete() {
180 free(p); // no-warning
183 void testStandardPlacementNewAfterDelete() {
186 p = new(p) int; // no-warning
190 // Smart pointer example
191 template <typename T>
192 struct SimpleSmartPointer {
195 explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
196 ~SimpleSmartPointer() {
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'}}
203 void testSimpleSmartPointerArrayNew() {
205 SimpleSmartPointer<int> a(new int);
209 SimpleSmartPointer<int> a(new int[4]);
213 void testSimpleSmartPointerMalloc() {
215 SimpleSmartPointer<int> a(new int);
219 SimpleSmartPointer<int> a((int *)malloc(4));