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 3 4#include "Inputs/system-header-simulator-objc.h" 5#include "Inputs/system-header-simulator-cxx.h" 6 7typedef __typeof__(sizeof(int)) size_t; 8void *malloc(size_t); 9void *realloc(void *ptr, size_t size); 10void *calloc(size_t nmemb, size_t size); 11char *strdup(const char *s); 12void __attribute((ownership_returns(malloc))) *my_malloc(size_t); 13 14void free(void *); 15void __attribute((ownership_takes(malloc, 1))) my_free(void *); 16 17//--------------------------------------------------------------- 18// Test if an allocation function matches deallocation function 19//--------------------------------------------------------------- 20 21//--------------- test malloc family 22void testMalloc1() { 23 int *p = (int *)malloc(sizeof(int)); 24 delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}} 25} 26 27void testMalloc2() { 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'}} 31} 32 33void testMalloc3() { 34 int *p = (int *)calloc(1, sizeof(int)); 35 delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}} 36} 37 38void testMalloc4(const char *s) { 39 char *p = strdup(s); 40 delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}} 41} 42 43void testMalloc5() { 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'}} 46} 47 48void testMalloc6() { 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}} 51} 52 53void testMalloc7() { 54 int *p = (int *)malloc(sizeof(int)); 55 delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}} 56} 57 58void testMalloc8() { 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[]}} 61} 62 63void testAlloca() { 64 int *p = (int *)__builtin_alloca(sizeof(int)); 65 delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}} 66} 67 68//--------------- test new family 69void testNew1() { 70 int *p = new int; 71 free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}} 72} 73 74void testNew2() { 75 int *p = (int *)operator new(0); 76 free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}} 77} 78 79void testNew3() { 80 int *p = new int[1]; 81 free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}} 82} 83 84void testNew4() { 85 int *p = new int; 86 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}} 87} 88 89void testNew5() { 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()}} 92} 93 94void testNew6() { 95 int *p = new int[1]; 96 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}} 97} 98 99int *allocInt() { 100 return new int; 101} 102void testNew7() { 103 int *p = allocInt(); 104 delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}} 105} 106 107void testNew8() { 108 int *p = (int *)operator new(0); 109 delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}} 110} 111 112int *allocIntArray(unsigned c) { 113 return new int[c]; 114} 115 116void testNew9() { 117 int *p = allocIntArray(1); 118 delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}} 119} 120 121void testNew10() { 122 int *p = (int *)operator new[](0); 123 delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}} 124} 125 126void testNew11(NSUInteger dataLength) { 127 int *p = new int; 128 NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}} 129} 130 131//------------------------------------------------------- 132// Check for intersection with unix.Malloc bounded with 133// unix.MismatchedDeallocator 134//------------------------------------------------------- 135 136// new/delete oparators are subjects of cplusplus.NewDelete. 137void testNewDeleteNoWarn() { 138 int i; 139 delete &i; // no-warning 140 141 int *p1 = new int; 142 delete ++p1; // no-warning 143 144 int *p2 = new int; 145 delete p2; 146 delete p2; // no-warning 147 148 int *p3 = new int; // no-warning 149} 150 151void testDeleteOpAfterFree() { 152 int *p = (int *)malloc(sizeof(int)); 153 free(p); 154 operator delete(p); // no-warning 155} 156 157void testDeleteAfterFree() { 158 int *p = (int *)malloc(sizeof(int)); 159 free(p); 160 delete p; // no-warning 161} 162 163void testStandardPlacementNewAfterFree() { 164 int *p = (int *)malloc(sizeof(int)); 165 free(p); 166 p = new(p) int; // no-warning 167} 168 169//--------------------------------------------------------------- 170// Check for intersection with cplusplus.NewDelete bounded with 171// unix.MismatchedDeallocator 172//--------------------------------------------------------------- 173 174// malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations 175void testMallocFreeNoWarn() { 176 int i; 177 free(&i); // no-warning 178 179 int *p1 = (int *)malloc(sizeof(int)); 180 free(++p1); // no-warning 181 182 int *p2 = (int *)malloc(sizeof(int)); 183 free(p2); 184 free(p2); // no-warning 185 186 int *p3 = (int *)malloc(sizeof(int)); // no-warning 187} 188 189void testFreeAfterDelete() { 190 int *p = new int; 191 delete p; 192 free(p); // no-warning 193} 194 195void testStandardPlacementNewAfterDelete() { 196 int *p = new int; 197 delete p; 198 p = new(p) int; // no-warning 199} 200 201 202// Smart pointer example 203template <typename T> 204struct SimpleSmartPointer { 205 T *ptr; 206 207 explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} 208 ~SimpleSmartPointer() { 209 delete ptr; 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'}} 212 } 213}; 214 215void testSimpleSmartPointerArrayNew() { 216 { 217 SimpleSmartPointer<int> a(new int); 218 } // no-warning 219 220 { 221 SimpleSmartPointer<int> a(new int[4]); 222 } 223} 224 225void testSimpleSmartPointerMalloc() { 226 { 227 SimpleSmartPointer<int> a(new int); 228 } // no-warning 229 230 { 231 SimpleSmartPointer<int> a((int *)malloc(4)); 232 } 233} 234