MismatchedDeallocator-checker-test.mm revision 0e2c34f92f00628d48968dfea096d36381f494cb
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 6typedef __typeof__(sizeof(int)) size_t; 7void *malloc(size_t); 8void *realloc(void *ptr, size_t size); 9void *calloc(size_t nmemb, size_t size); 10char *strdup(const char *s); 11void __attribute((ownership_returns(malloc))) *my_malloc(size_t); 12 13void free(void *); 14void __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 21void 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 26void 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 32void 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 37void 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 42void 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 47void 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 52void 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 57void 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 62void 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 68void testNew1() { 69 int *p = new int; 70 free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}} 71} 72 73void 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 78void 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 83void 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 88void 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 93void 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 98void testNew7() { 99 int *p = new int; 100 delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}} 101} 102 103void testNew8() { 104 int *p = (int *)operator new(0); 105 delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}} 106} 107 108void testNew9() { 109 int *p = new int[1]; 110 delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} 111} 112 113void testNew10() { 114 int *p = (int *)operator new[](0); 115 delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}} 116} 117 118void testNew11(NSUInteger dataLength) { 119 int *p = new int; 120 NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}} 121} 122 123//------------------------------------------------------- 124// Check for intersection with unix.Malloc bounded with 125// unix.MismatchedDeallocator 126//------------------------------------------------------- 127 128// new/delete oparators are subjects of cplusplus.NewDelete. 129void testNewDeleteNoWarn() { 130 int i; 131 delete &i; // no-warning 132 133 int *p1 = new int; 134 delete ++p1; // no-warning 135 136 int *p2 = new int; 137 delete p2; 138 delete p2; // no-warning 139 140 int *p3 = new int; // no-warning 141} 142 143void testDeleteOpAfterFree() { 144 int *p = (int *)malloc(sizeof(int)); 145 free(p); 146 operator delete(p); // no-warning 147} 148 149void testDeleteAfterFree() { 150 int *p = (int *)malloc(sizeof(int)); 151 free(p); 152 delete p; // no-warning 153} 154 155void testStandardPlacementNewAfterFree() { 156 int *p = (int *)malloc(sizeof(int)); 157 free(p); 158 p = new(p) int; // no-warning 159} 160 161//--------------------------------------------------------------- 162// Check for intersection with cplusplus.NewDelete bounded with 163// unix.MismatchedDeallocator 164//--------------------------------------------------------------- 165 166// malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations 167void testMallocFreeNoWarn() { 168 int i; 169 free(&i); // no-warning 170 171 int *p1 = (int *)malloc(sizeof(int)); 172 free(++p1); // no-warning 173 174 int *p2 = (int *)malloc(sizeof(int)); 175 free(p2); 176 free(p2); // no-warning 177 178 int *p3 = (int *)malloc(sizeof(int)); // no-warning 179} 180 181void testFreeAfterDelete() { 182 int *p = new int; 183 delete p; 184 free(p); // no-warning 185} 186 187void testStandardPlacementNewAfterDelete() { 188 int *p = new int; 189 delete p; 190 p = new(p) int; // no-warning 191} 192 193 194// Smart pointer example 195template <typename T> 196struct SimpleSmartPointer { 197 T *ptr; 198 199 explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} 200 ~SimpleSmartPointer() { 201 delete ptr; 202 // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} 203 // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} 204 } 205}; 206 207void testSimpleSmartPointerArrayNew() { 208 { 209 SimpleSmartPointer<int> a(new int); 210 } // no-warning 211 212 { 213 SimpleSmartPointer<int> a(new int[4]); 214 } 215} 216 217void testSimpleSmartPointerMalloc() { 218 { 219 SimpleSmartPointer<int> a(new int); 220 } // no-warning 221 222 { 223 SimpleSmartPointer<int> a((int *)malloc(4)); 224 } 225} 226