1 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 -analyzer-config cfg-rich-constructors=false %s > %t 2>&1 2 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,WARNINGS %s 3 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 -analyzer-config cfg-rich-constructors=true %s > %t 2>&1 4 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,ANALYZER %s 5 6 // This file tests how we construct two different flavors of the Clang CFG - 7 // the CFG used by the Sema analysis-based warnings and the CFG used by the 8 // static analyzer. The difference in the behavior is checked via FileCheck 9 // prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer 10 // flags, no new run lines should be added - just these flags would go to the 11 // respective line depending on where is it turned on and where is it turned 12 // off. Feel free to add tests that test only one of the CFG flavors if you're 13 // not sure how the other flavor is supposed to work in your case. 14 15 // CHECK-LABEL: void checkWrap(int i) 16 // CHECK: ENTRY 17 // CHECK-NEXT: Succs (1): B1 18 // CHECK: [B1] 19 // CHECK: Succs (21): B2 B3 B4 B5 B6 B7 B8 B9 20 // CHECK: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 21 // CHECK: B20 B21 B0 22 // CHECK: [B0 (EXIT)] 23 // CHECK-NEXT: Preds (21): B2 B3 B4 B5 B6 B7 B8 B9 24 // CHECK-NEXT: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 25 // CHECK-NEXT: B20 B21 B1 26 void checkWrap(int i) { 27 switch(i) { 28 case 0: break; 29 case 1: break; 30 case 2: break; 31 case 3: break; 32 case 4: break; 33 case 5: break; 34 case 6: break; 35 case 7: break; 36 case 8: break; 37 case 9: break; 38 case 10: break; 39 case 11: break; 40 case 12: break; 41 case 13: break; 42 case 14: break; 43 case 15: break; 44 case 16: break; 45 case 17: break; 46 case 18: break; 47 case 19: break; 48 } 49 } 50 51 // CHECK-LABEL: void checkDeclStmts() 52 // CHECK: ENTRY 53 // CHECK-NEXT: Succs (1): B1 54 // CHECK: [B1] 55 // CHECK-NEXT: 1: int i; 56 // CHECK-NEXT: 2: int j; 57 // CHECK-NEXT: 3: 1 58 // CHECK-NEXT: 4: int k = 1; 59 // CHECK-NEXT: 5: int l; 60 // CHECK-NEXT: 6: 2 61 // CHECK-NEXT: 7: int m = 2; 62 // WARNINGS-NEXT: (CXXConstructExpr, struct standalone) 63 // ANALYZER-NEXT: (CXXConstructExpr, [B1.9], struct standalone) 64 // CHECK-NEXT: 9: struct standalone myStandalone; 65 // WARNINGS-NEXT: (CXXConstructExpr, struct (anonymous struct at {{.*}})) 66 // ANALYZER-NEXT: (CXXConstructExpr, [B1.11], struct (anonymous struct at {{.*}})) 67 // CHECK-NEXT: 11: struct (anonymous struct at {{.*}}) myAnon; 68 // WARNINGS-NEXT: (CXXConstructExpr, struct named) 69 // ANALYZER-NEXT: (CXXConstructExpr, [B1.13], struct named) 70 // CHECK-NEXT: 13: struct named myNamed; 71 // CHECK-NEXT: Preds (1): B2 72 // CHECK-NEXT: Succs (1): B0 73 void checkDeclStmts() { 74 int i, j; 75 int k = 1, l, m = 2; 76 77 struct standalone { int x, y; }; 78 struct standalone myStandalone; 79 80 struct { int x, y; } myAnon; 81 82 struct named { int x, y; } myNamed; 83 84 static_assert(1, "abc"); 85 } 86 87 // CHECK-LABEL: void F(EmptyE e) 88 // CHECK: ENTRY 89 // CHECK-NEXT: Succs (1): B1 90 // CHECK: [B1] 91 // CHECK-NEXT: 1: e 92 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, enum EmptyE) 93 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, IntegralCast, int) 94 // CHECK-NEXT: T: switch [B1.3] 95 // CHECK-NEXT: Preds (1): B2 96 // CHECK-NEXT: Succs (1): B0 97 // CHECK: [B0 (EXIT)] 98 // CHECK-NEXT: Preds (1): B1 99 enum EmptyE {}; 100 void F(EmptyE e) { 101 switch (e) {} 102 } 103 104 // CHECK-LABEL: void testBuiltinSize() 105 // CHECK: ENTRY 106 // CHECK-NEXT: Succs (1): B1 107 // CHECK: [B1] 108 // CHECK-NEXT: 1: __builtin_object_size 109 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, BuiltinFnToFnPtr, unsigned long (*)(const void *, int) noexcept) 110 // CHECK-NEXT: 3: [B1.2](dummy(), 0) 111 // CHECK-NEXT: 4: (void)[B1.3] (CStyleCastExpr, ToVoid, void) 112 // CHECK-NEXT: Preds (1): B2 113 // CHECK-NEXT: Succs (1): B0 114 // CHECK: [B0 (EXIT)] 115 // CHECK-NEXT: Preds (1): B1 116 void testBuiltinSize() { 117 extern int *dummy(); 118 (void)__builtin_object_size(dummy(), 0); 119 } 120 121 122 class A { 123 public: 124 A() {} 125 ~A() {} 126 }; 127 128 // CHECK-LABEL: void test_deletedtor() 129 // CHECK: [B2 (ENTRY)] 130 // CHECK-NEXT: Succs (1): B1 131 // CHECK: [B1] 132 // CHECK-NEXT: 1: CFGNewAllocator(A *) 133 // WARNINGS-NEXT: 2: (CXXConstructExpr, class A) 134 // ANALYZER-NEXT: 2: (CXXConstructExpr, [B1.3], class A) 135 // CHECK-NEXT: 3: new A([B1.2]) 136 // CHECK-NEXT: 4: A *a = new A(); 137 // CHECK-NEXT: 5: a 138 // CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *) 139 // CHECK-NEXT: 7: [B1.6]->~A() (Implicit destructor) 140 // CHECK-NEXT: 8: delete [B1.6] 141 // CHECK-NEXT: Preds (1): B2 142 // CHECK-NEXT: Succs (1): B0 143 // CHECK: [B0 (EXIT)] 144 // CHECK-NEXT: Preds (1): B1 145 void test_deletedtor() { 146 A *a = new A(); 147 delete a; 148 } 149 150 // CHECK-LABEL: void test_deleteArraydtor() 151 // CHECK: [B2 (ENTRY)] 152 // CHECK-NEXT: Succs (1): B1 153 // CHECK: [B1] 154 // CHECK-NEXT: 1: 5 155 // CHECK-NEXT: 2: CFGNewAllocator(A *) 156 // WARNINGS-NEXT: 3: (CXXConstructExpr, class A [5]) 157 // ANALYZER-NEXT: 3: (CXXConstructExpr, [B1.4], class A [5]) 158 // CHECK-NEXT: 4: new A {{\[\[}}B1.1]] 159 // CHECK-NEXT: 5: A *a = new A [5]; 160 // CHECK-NEXT: 6: a 161 // CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, class A *) 162 // CHECK-NEXT: 8: [B1.7]->~A() (Implicit destructor) 163 // CHECK-NEXT: 9: delete [] [B1.7] 164 // CHECK-NEXT: Preds (1): B2 165 // CHECK-NEXT: Succs (1): B0 166 // CHECK: [B0 (EXIT)] 167 // CHECK-NEXT: Preds (1): B1 168 void test_deleteArraydtor() { 169 A *a = new A[5]; 170 delete[] a; 171 } 172 173 174 namespace NoReturnSingleSuccessor { 175 struct A { 176 A(); 177 ~A(); 178 }; 179 180 struct B : public A { 181 B(); 182 ~B() __attribute__((noreturn)); 183 }; 184 185 // CHECK-LABEL: int test1(int *x) 186 // CHECK: 1: 1 187 // CHECK-NEXT: 2: return 188 // CHECK-NEXT: ~B() (Implicit destructor) 189 // CHECK-NEXT: Preds (1) 190 // CHECK-NEXT: Succs (1): B0 191 int test1(int *x) { 192 B b; 193 if (x) 194 return 1; 195 } 196 197 // CHECK-LABEL: int test2(int *x) 198 // CHECK: 1: 1 199 // CHECK-NEXT: 2: return 200 // CHECK-NEXT: destructor 201 // CHECK-NEXT: Preds (1) 202 // CHECK-NEXT: Succs (1): B0 203 int test2(int *x) { 204 const A& a = B(); 205 if (x) 206 return 1; 207 } 208 } 209 210 // Test CFG support for "extending" an enum. 211 // CHECK-LABEL: int test_enum_with_extension(enum MyEnum value) 212 // CHECK: [B7 (ENTRY)] 213 // CHECK-NEXT: Succs (1): B2 214 // CHECK: [B1] 215 // CHECK-NEXT: 1: x 216 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 217 // CHECK-NEXT: 3: return [B1.2]; 218 // CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable) 219 // CHECK-NEXT: Succs (1): B0 220 // CHECK: [B2] 221 // CHECK-NEXT: 1: 0 222 // CHECK-NEXT: 2: int x = 0; 223 // CHECK-NEXT: 3: value 224 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum) 225 // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) 226 // CHECK-NEXT: T: switch [B2.5] 227 // CHECK-NEXT: Preds (1): B7 228 // CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable) 229 // CHECK: [B3] 230 // CHECK-NEXT: case D: 231 // CHECK-NEXT: 1: 4 232 // CHECK-NEXT: 2: x 233 // CHECK-NEXT: 3: [B3.2] = [B3.1] 234 // CHECK-NEXT: T: break; 235 // CHECK-NEXT: Preds (1): B2 236 // CHECK-NEXT: Succs (1): B1 237 // CHECK: [B4] 238 // CHECK-NEXT: case C: 239 // CHECK-NEXT: 1: 3 240 // CHECK-NEXT: 2: x 241 // CHECK-NEXT: 3: [B4.2] = [B4.1] 242 // CHECK-NEXT: T: break; 243 // CHECK-NEXT: Preds (1): B2 244 // CHECK-NEXT: Succs (1): B1 245 // CHECK: [B5] 246 // CHECK-NEXT: case B: 247 // CHECK-NEXT: 1: 2 248 // CHECK-NEXT: 2: x 249 // CHECK-NEXT: 3: [B5.2] = [B5.1] 250 // CHECK-NEXT: T: break; 251 // CHECK-NEXT: Preds (1): B2 252 // CHECK-NEXT: Succs (1): B1 253 // CHECK: [B6] 254 // CHECK-NEXT: case A: 255 // CHECK-NEXT: 1: 1 256 // CHECK-NEXT: 2: x 257 // CHECK-NEXT: 3: [B6.2] = [B6.1] 258 // CHECK-NEXT: T: break; 259 // CHECK-NEXT: Preds (1): B2 260 // CHECK-NEXT: Succs (1): B1 261 // CHECK: [B0 (EXIT)] 262 // CHECK-NEXT: Preds (1): B1 263 enum MyEnum { A, B, C }; 264 static const enum MyEnum D = (enum MyEnum) 32; 265 266 int test_enum_with_extension(enum MyEnum value) { 267 int x = 0; 268 switch (value) { 269 case A: x = 1; break; 270 case B: x = 2; break; 271 case C: x = 3; break; 272 case D: x = 4; break; 273 } 274 return x; 275 } 276 277 // CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value) 278 // CHECK: [B7 (ENTRY)] 279 // CHECK-NEXT: Succs (1): B2 280 // CHECK: [B1] 281 // CHECK-NEXT: 1: x 282 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 283 // CHECK-NEXT: 3: return [B1.2]; 284 // CHECK-NEXT: Preds (4): B3 B4 B5 B6 285 // CHECK-NEXT: Succs (1): B0 286 // CHECK: [B2] 287 // CHECK-NEXT: 1: 0 288 // CHECK-NEXT: 2: int x = 0; 289 // CHECK-NEXT: 3: value 290 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum) 291 // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) 292 // CHECK-NEXT: T: switch [B2.5] 293 // CHECK-NEXT: Preds (1): B7 294 // CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable) 295 // CHECK: [B3] 296 // CHECK-NEXT: default: 297 // CHECK-NEXT: 1: 4 298 // CHECK-NEXT: 2: x 299 // CHECK-NEXT: 3: [B3.2] = [B3.1] 300 // CHECK-NEXT: T: break; 301 // CHECK-NEXT: Preds (1): B2(Unreachable) 302 // CHECK-NEXT: Succs (1): B1 303 // CHECK: [B4] 304 // CHECK-NEXT: case C: 305 // CHECK-NEXT: 1: 3 306 // CHECK-NEXT: 2: x 307 // CHECK-NEXT: 3: [B4.2] = [B4.1] 308 // CHECK-NEXT: T: break; 309 // CHECK-NEXT: Preds (1): B2 310 // CHECK-NEXT: Succs (1): B1 311 // CHECK: [B5] 312 // CHECK-NEXT: case B: 313 // CHECK-NEXT: 1: 2 314 // CHECK-NEXT: 2: x 315 // CHECK-NEXT: 3: [B5.2] = [B5.1] 316 // CHECK-NEXT: T: break; 317 // CHECK-NEXT: Preds (1): B2 318 // CHECK-NEXT: Succs (1): B1 319 // CHECK: [B6] 320 // CHECK-NEXT: case A: 321 // CHECK-NEXT: 1: 1 322 // CHECK-NEXT: 2: x 323 // CHECK-NEXT: 3: [B6.2] = [B6.1] 324 // CHECK-NEXT: T: break; 325 // CHECK-NEXT: Preds (1): B2 326 // CHECK-NEXT: Succs (1): B1 327 // CHECK: [B0 (EXIT)] 328 // CHECK-NEXT: Preds (1): B1 329 int test_enum_with_extension_default(enum MyEnum value) { 330 int x = 0; 331 switch (value) { 332 case A: x = 1; break; 333 case B: x = 2; break; 334 case C: x = 3; break; 335 default: x = 4; break; 336 } 337 return x; 338 } 339 340 341 // CHECK-LABEL: void test_placement_new() 342 // CHECK: [B2 (ENTRY)] 343 // CHECK-NEXT: Succs (1): B1 344 // CHECK: [B1] 345 // CHECK-NEXT: 1: int buffer[16]; 346 // CHECK-NEXT: 2: buffer 347 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *) 348 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) 349 // CHECK-NEXT: 5: CFGNewAllocator(MyClass *) 350 // WARNINGS-NEXT: 6: (CXXConstructExpr, class MyClass) 351 // ANALYZER-NEXT: 6: (CXXConstructExpr, [B1.7], class MyClass) 352 // CHECK-NEXT: 7: new ([B1.4]) MyClass([B1.6]) 353 // CHECK-NEXT: 8: MyClass *obj = new (buffer) MyClass(); 354 // CHECK-NEXT: Preds (1): B2 355 // CHECK-NEXT: Succs (1): B0 356 // CHECK: [B0 (EXIT)] 357 // CHECK-NEXT: Preds (1): B1 358 359 extern void* operator new (unsigned long sz, void* v); 360 extern void* operator new[] (unsigned long sz, void* ptr); 361 362 class MyClass { 363 public: 364 MyClass() {} 365 ~MyClass() {} 366 }; 367 368 void test_placement_new() { 369 int buffer[16]; 370 MyClass* obj = new (buffer) MyClass(); 371 } 372 373 // CHECK-LABEL: void test_placement_new_array() 374 // CHECK: [B2 (ENTRY)] 375 // CHECK-NEXT: Succs (1): B1 376 // CHECK: [B1] 377 // CHECK-NEXT: 1: int buffer[16]; 378 // CHECK-NEXT: 2: buffer 379 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *) 380 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) 381 // CHECK-NEXT: 5: 5 382 // CHECK-NEXT: 6: CFGNewAllocator(MyClass *) 383 // WARNINGS-NEXT: 7: (CXXConstructExpr, class MyClass [5]) 384 // ANALYZER-NEXT: 7: (CXXConstructExpr, [B1.8], class MyClass [5]) 385 // CHECK-NEXT: 8: new ([B1.4]) MyClass {{\[\[}}B1.5]] 386 // CHECK-NEXT: 9: MyClass *obj = new (buffer) MyClass [5]; 387 // CHECK-NEXT: Preds (1): B2 388 // CHECK-NEXT: Succs (1): B0 389 // CHECK: [B0 (EXIT)] 390 // CHECK-NEXT: Preds (1): B1 391 392 void test_placement_new_array() { 393 int buffer[16]; 394 MyClass* obj = new (buffer) MyClass[5]; 395 } 396 397 398 // CHECK-LABEL: void test_lifetime_extended_temporaries() 399 // CHECK: [B1] 400 struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); }; 401 struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; }; 402 struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; }; 403 void test_lifetime_extended_temporaries() { 404 // CHECK: LifetimeExtend(1); 405 // CHECK-NEXT: : 1 406 // CHECK-NEXT: ~LifetimeExtend() 407 // CHECK-NOT: ~LifetimeExtend() 408 { 409 const LifetimeExtend &l = LifetimeExtend(1); 410 1; 411 } 412 // CHECK: LifetimeExtend(2) 413 // CHECK-NEXT: ~LifetimeExtend() 414 // CHECK-NEXT: : 2 415 // CHECK-NOT: ~LifetimeExtend() 416 { 417 // No life-time extension. 418 const int &l = (LifetimeExtend(2), 2); 419 2; 420 } 421 // CHECK: LifetimeExtend(3) 422 // CHECK-NEXT: : 3 423 // CHECK-NEXT: ~LifetimeExtend() 424 // CHECK-NOT: ~LifetimeExtend() 425 { 426 // The last one is lifetime extended. 427 const LifetimeExtend &l = (3, LifetimeExtend(3)); 428 3; 429 } 430 // CHECK: LifetimeExtend(4) 431 // CHECK-NEXT: ~LifetimeExtend() 432 // CHECK-NEXT: ~LifetimeExtend() 433 // CHECK-NEXT: : 4 434 // CHECK-NOT: ~LifetimeExtend() 435 { 436 Aggregate a{LifetimeExtend(4), LifetimeExtend(4)}; 437 4; 438 } 439 // CHECK: LifetimeExtend(5) 440 // CHECK-NEXT: : 5 441 // FIXME: We want to emit the destructors of the lifetime 442 // extended variables here. 443 // CHECK-NOT: ~LifetimeExtend() 444 { 445 AggregateRef a{LifetimeExtend(5), LifetimeExtend(5)}; 446 5; 447 } 448 // FIXME: Add tests for lifetime extension via subobject 449 // references (LifetimeExtend().some_member). 450 } 451 452 453 // CHECK-LABEL: template<> int *PR18472<int>() 454 // CHECK: [B2 (ENTRY)] 455 // CHECK-NEXT: Succs (1): B1 456 // CHECK: [B1] 457 // CHECK-NEXT: 1: 0 458 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t) 459 // CHECK-NEXT: 3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t) 460 // CHECK-NEXT: 4: CFGNewAllocator(int *) 461 // CHECK-NEXT: 5: new (([B1.3])) int 462 // CHECK-NEXT: 6: return [B1.5]; 463 // CHECK-NEXT: Preds (1): B2 464 // CHECK-NEXT: Succs (1): B0 465 // CHECK: [B0 (EXIT)] 466 // CHECK-NEXT: Preds (1): B1 467 468 extern "C" typedef int *PR18472_t; 469 void *operator new (unsigned long, PR18472_t); 470 template <class T> T *PR18472() { 471 return new (((PR18472_t) 0)) T; 472 } 473 void PR18472_helper() { 474 PR18472<int>(); 475 } 476 477