1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify -analyzer-config eagerly-assume=false %s 2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify -analyzer-config eagerly-assume=false %s 3 #include "Inputs/system-header-simulator-cxx.h" 4 5 void clang_analyzer_eval(bool); 6 7 typedef __typeof__(sizeof(int)) size_t; 8 extern "C" void *malloc(size_t); 9 extern "C" void free(void *); 10 11 int someGlobal; 12 13 class SomeClass { 14 public: 15 void f(int *p); 16 }; 17 18 void testImplicitlyDeclaredGlobalNew() { 19 if (someGlobal != 0) 20 return; 21 22 // This used to crash because the global operator new is being implicitly 23 // declared and it does not have a valid source location. (PR13090) 24 void *x = ::operator new(0); 25 ::operator delete(x); 26 27 // Check that the new/delete did not invalidate someGlobal; 28 clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} 29 } 30 31 void *testPlacementNew() { 32 int *x = (int *)malloc(sizeof(int)); 33 *x = 1; 34 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}}; 35 36 void *y = new (x) int; 37 clang_analyzer_eval(x == y); // expected-warning{{TRUE}}; 38 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}}; 39 40 return y; 41 } 42 43 void *operator new(size_t, size_t, int *); 44 void *testCustomNew() { 45 int x[1] = {1}; 46 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}}; 47 48 void *y = new (0, x) int; 49 clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}}; 50 51 return y; // no-warning 52 } 53 54 void *operator new(size_t, void *, void *); 55 void *testCustomNewMalloc() { 56 int *x = (int *)malloc(sizeof(int)); 57 58 // Should be no-warning (the custom allocator could have freed x). 59 void *y = new (0, x) int; // no-warning 60 61 return y; 62 } 63 64 void testScalarInitialization() { 65 int *n = new int(3); 66 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} 67 68 new (n) int(); 69 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} 70 71 new (n) int{3}; 72 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} 73 74 new (n) int{}; 75 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} 76 } 77 78 struct PtrWrapper { 79 int *x; 80 81 PtrWrapper(int *input) : x(input) {} 82 }; 83 84 PtrWrapper *testNewInvalidation() { 85 // Ensure that we don't consider this a leak. 86 return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning 87 } 88 89 void testNewInvalidationPlacement(PtrWrapper *w) { 90 // Ensure that we don't consider this a leak. 91 new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning 92 } 93 94 int **testNewInvalidationScalar() { 95 // Ensure that we don't consider this a leak. 96 return new (int *)(static_cast<int *>(malloc(4))); // no-warning 97 } 98 99 void testNewInvalidationScalarPlacement(int **p) { 100 // Ensure that we don't consider this a leak. 101 new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning 102 } 103 104 void testCacheOut(PtrWrapper w) { 105 extern bool coin(); 106 if (coin()) 107 w.x = 0; 108 new (&w.x) (int*)(0); // we cache out here; don't crash 109 } 110 111 void testUseAfter(int *p) { 112 SomeClass *c = new SomeClass; 113 free(p); 114 c->f(p); // expected-warning{{Use of memory after it is freed}} 115 delete c; 116 } 117 118 //-------------------------------------------------------------------- 119 // Check for intersection with other checkers from MallocChecker.cpp 120 // bounded with unix.Malloc 121 //-------------------------------------------------------------------- 122 123 // new/delete oparators are subjects of cplusplus.NewDelete. 124 void testNewDeleteNoWarn() { 125 int i; 126 delete &i; // no-warning 127 128 int *p1 = new int; 129 delete ++p1; // no-warning 130 131 int *p2 = new int; 132 delete p2; 133 delete p2; // no-warning 134 135 int *p3 = new int; // no-warning 136 } 137 138 // unix.Malloc does not know about operators new/delete. 139 void testDeleteMallocked() { 140 int *x = (int *)malloc(sizeof(int)); 141 delete x; // FIXME: Should detect pointer escape and keep silent after 'delete' is modeled properly. 142 } // expected-warning{{Potential leak of memory pointed to by 'x'}} 143 144 void testDeleteOpAfterFree() { 145 int *p = (int *)malloc(sizeof(int)); 146 free(p); 147 operator delete(p); // expected-warning{{Use of memory after it is freed}} 148 } 149 150 void testDeleteAfterFree() { 151 int *p = (int *)malloc(sizeof(int)); 152 free(p); 153 delete p; // expected-warning{{Use of memory after it is freed}} 154 } 155 156 void testStandardPlacementNewAfterFree() { 157 int *p = (int *)malloc(sizeof(int)); 158 free(p); 159 p = new(p) int; // expected-warning{{Use of memory after it is freed}} 160 } 161 162 void testCustomPlacementNewAfterFree() { 163 int *p = (int *)malloc(sizeof(int)); 164 free(p); 165 p = new(0, p) int; // expected-warning{{Use of memory after it is freed}} 166 } 167 168 void testUsingThisAfterDelete() { 169 SomeClass *c = new SomeClass; 170 delete c; 171 c->f(0); // no-warning 172 } 173 174 void testAggregateNew() { 175 struct Point { int x, y; }; 176 new Point{1, 2}; // no crash 177 178 Point p; 179 new (&p) Point{1, 2}; // no crash 180 clang_analyzer_eval(p.x == 1); // expected-warning{{TRUE}} 181 clang_analyzer_eval(p.y == 2); // expected-warning{{TRUE}} 182 } 183 184 //-------------------------------- 185 // Incorrectly-modelled behavior 186 //-------------------------------- 187 188 int testNoInitialization() { 189 int *n = new int; 190 191 // Should warn that *n is uninitialized. 192 if (*n) { // no-warning 193 delete n; 194 return 0; 195 } 196 delete n; 197 return 1; 198 } 199 200 int testNoInitializationPlacement() { 201 int n; 202 new (&n) int; 203 204 if (n) { // expected-warning{{Branch condition evaluates to a garbage value}} 205 return 0; 206 } 207 return 1; 208 } 209 210 // Test modelling destructor call on call to delete 211 class IntPair{ 212 public: 213 int x; 214 int y; 215 IntPair() {}; 216 ~IntPair() {x = x/y;}; //expected-warning {{Division by zero}} 217 }; 218 219 void testCallToDestructor() { 220 IntPair *b = new IntPair(); 221 b->x = 1; 222 b->y = 0; 223 delete b; // This results in divide by zero in destructor 224 } 225 226 // Test Deleting a value that's passed as an argument. 227 class DerefClass{ 228 public: 229 int *x; 230 DerefClass() {}; 231 ~DerefClass() {*x = 1;}; //expected-warning {{Dereference of null pointer (loaded from field 'x')}} 232 }; 233 234 void testDestCall(DerefClass *arg) { 235 delete arg; 236 } 237 238 void test_delete_dtor_Arg() { 239 DerefClass *pair = new DerefClass(); 240 pair->x = 0; 241 testDestCall(pair); 242 } 243 244 //Deleting the address of a local variable, null pointer 245 void abort(void) __attribute__((noreturn)); 246 247 class NoReturnDtor { 248 public: 249 NoReturnDtor() {} 250 ~NoReturnDtor() {abort();} 251 }; 252 253 void test_delete_dtor_LocalVar() { 254 NoReturnDtor test; 255 delete &test; // no warn or crash 256 } 257 258 class DerivedNoReturn:public NoReturnDtor { 259 public: 260 DerivedNoReturn() {}; 261 ~DerivedNoReturn() {}; 262 }; 263 264 void testNullDtorDerived() { 265 DerivedNoReturn *p = new DerivedNoReturn(); 266 delete p; // Calls the base destructor which aborts, checked below 267 clang_analyzer_eval(true); // no warn 268 } 269 270 //Deleting a non-class pointer should not crash/warn 271 void test_var_delete() { 272 int *v = new int; 273 delete v; // no crash/warn 274 clang_analyzer_eval(true); // expected-warning{{TRUE}} 275 } 276 277 void test_array_delete() { 278 class C { 279 public: 280 ~C() {} 281 }; 282 283 auto c1 = new C[2][3]; 284 delete[] c1; // no-crash // no-warning 285 286 C c2[4]; 287 // FIXME: Should warn. 288 delete[] &c2; // no-crash 289 290 C c3[7][6]; 291 // FIXME: Should warn. 292 delete[] &c3; // no-crash 293 } 294 295 void testDeleteNull() { 296 NoReturnDtor *foo = 0; 297 delete foo; // should not call destructor, checked below 298 clang_analyzer_eval(true); // expected-warning{{TRUE}} 299 } 300 301 void testNullAssigneddtor() { 302 NoReturnDtor *p = 0; 303 NoReturnDtor *s = p; 304 delete s; // should not call destructor, checked below 305 clang_analyzer_eval(true); // expected-warning{{TRUE}} 306 } 307 308 void deleteArg(NoReturnDtor *test) { 309 delete test; 310 } 311 312 void testNulldtorArg() { 313 NoReturnDtor *p = 0; 314 deleteArg(p); 315 clang_analyzer_eval(true); // expected-warning{{TRUE}} 316 } 317 318 void testDeleteUnknown(NoReturnDtor *foo) { 319 delete foo; // should assume non-null and call noreturn destructor 320 clang_analyzer_eval(true); // no-warning 321 } 322 323 void testArrayNull() { 324 NoReturnDtor *fooArray = 0; 325 delete[] fooArray; // should not call destructor, checked below 326 clang_analyzer_eval(true); // expected-warning{{TRUE}} 327 } 328 329 void testArrayDestr() { 330 NoReturnDtor *p = new NoReturnDtor[2]; 331 delete[] p; // Calls the base destructor which aborts, checked below 332 //TODO: clang_analyzer_eval should not be called 333 clang_analyzer_eval(true); // expected-warning{{TRUE}} 334 } 335 336 // Invalidate Region even in case of default destructor 337 class InvalidateDestTest { 338 public: 339 int x; 340 int *y; 341 ~InvalidateDestTest(); 342 }; 343 344 int test_member_invalidation() { 345 346 //test invalidation of member variable 347 InvalidateDestTest *test = new InvalidateDestTest(); 348 test->x = 5; 349 int *k = &(test->x); 350 clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}} 351 delete test; 352 clang_analyzer_eval(*k == 5); // expected-warning{{UNKNOWN}} 353 354 //test invalidation of member pointer 355 int localVar = 5; 356 test = new InvalidateDestTest(); 357 test->y = &localVar; 358 delete test; 359 clang_analyzer_eval(localVar == 5); // expected-warning{{UNKNOWN}} 360 361 // Test aray elements are invalidated. 362 int Var1 = 5; 363 int Var2 = 5; 364 InvalidateDestTest *a = new InvalidateDestTest[2]; 365 a[0].y = &Var1; 366 a[1].y = &Var2; 367 delete[] a; 368 clang_analyzer_eval(Var1 == 5); // expected-warning{{UNKNOWN}} 369 clang_analyzer_eval(Var2 == 5); // expected-warning{{UNKNOWN}} 370 return 0; 371 } 372