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