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