692 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -Wno-error=invalid-gnu-asm-cast -std=c++11 -analyzer-config cfg-rich-constructors=false %s > %t 2>&12// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,WARNINGS %s3// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -Wno-error=invalid-gnu-asm-cast -std=c++11 -analyzer-config cfg-rich-constructors=true %s > %t 2>&14// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,ANALYZER %s5 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 the8// static analyzer. The difference in the behavior is checked via FileCheck9// prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer10// flags, no new run lines should be added - just these flags would go to the11// respective line depending on where is it turned on and where is it turned12// off. Feel free to add tests that test only one of the CFG flavors if you're13// not sure how the other flavor is supposed to work in your case.14 15// CHECK-LABEL: void checkDeclStmts()16// CHECK: ENTRY17// CHECK-NEXT: Succs (1): B118// CHECK: [B1]19// CHECK-NEXT: 1: int i;20// CHECK-NEXT: 2: int j;21// CHECK-NEXT: 3: 122// CHECK-NEXT: 4: int k = 1;23// CHECK-NEXT: 5: int l;24// CHECK-NEXT: 6: 225// CHECK-NEXT: 7: int m = 2;26// WARNINGS-NEXT: (CXXConstructExpr, struct standalone)27// ANALYZER-NEXT: (CXXConstructExpr, [B1.9], struct standalone)28// CHECK-NEXT: 9: struct standalone myStandalone;29// WARNINGS-NEXT: (CXXConstructExpr, struct (unnamed struct at {{.*}}))30// ANALYZER-NEXT: (CXXConstructExpr, [B1.11], struct (unnamed struct at {{.*}}))31// CHECK-NEXT: 11: struct (unnamed struct at {{.*}}) myAnon;32// WARNINGS-NEXT: (CXXConstructExpr, struct named)33// ANALYZER-NEXT: (CXXConstructExpr, [B1.13], struct named)34// CHECK-NEXT: 13: struct named myNamed;35// CHECK-NEXT: Preds (1): B236// CHECK-NEXT: Succs (1): B037void checkDeclStmts() {38 int i, j;39 int k = 1, l, m = 2;40 41 struct standalone { int x, y; };42 struct standalone myStandalone;43 44 struct { int x, y; } myAnon;45 46 struct named { int x, y; } myNamed;47 48 static_assert(1, "abc");49}50 51// CHECK-LABEL: void F(EmptyE e)52// CHECK: ENTRY53// CHECK-NEXT: Succs (1): B154// CHECK: [B1]55// CHECK-NEXT: 1: e56// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, EmptyE)57// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, IntegralCast, int)58// CHECK-NEXT: T: switch [B1.3]59// CHECK-NEXT: Preds (1): B260// CHECK-NEXT: Succs (1): B061// CHECK: [B0 (EXIT)]62// CHECK-NEXT: Preds (1): B163enum EmptyE {};64void F(EmptyE e) {65 switch (e) {}66}67 68// CHECK-LABEL: void testBuiltinSize()69// CHECK: ENTRY70// CHECK-NEXT: Succs (1): B171// CHECK: [B1]72// CHECK-NEXT: 1: __builtin_object_size73// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, BuiltinFnToFnPtr, __size_t (*)(const void *, int) noexcept)74// CHECK-NEXT: 3: [B1.2](dummy(), 0)75// CHECK-NEXT: 4: (void)[B1.3] (CStyleCastExpr, ToVoid, void)76// CHECK-NEXT: Preds (1): B277// CHECK-NEXT: Succs (1): B078// CHECK: [B0 (EXIT)]79// CHECK-NEXT: Preds (1): B180void testBuiltinSize() {81 extern int *dummy();82 (void)__builtin_object_size(dummy(), 0);83}84 85class A {86public:87 A() {}88 ~A() {}89};90 91// CHECK-LABEL: void test_deletedtor()92// CHECK: [B2 (ENTRY)]93// CHECK-NEXT: Succs (1): B194// CHECK: [B1]95// CHECK-NEXT: 1: CFGNewAllocator(A *)96// WARNINGS-NEXT: 2: (CXXConstructExpr, A)97// ANALYZER-NEXT: 2: (CXXConstructExpr, [B1.3], A)98// CHECK-NEXT: 3: new A([B1.2])99// CHECK-NEXT: 4: A *a = new A();100// CHECK-NEXT: 5: a101// CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, A *)102// CHECK-NEXT: 7: [B1.6]->~A() (Implicit destructor)103// CHECK-NEXT: 8: delete [B1.6]104// CHECK-NEXT: Preds (1): B2105// CHECK-NEXT: Succs (1): B0106// CHECK: [B0 (EXIT)]107// CHECK-NEXT: Preds (1): B1108void test_deletedtor() {109 A *a = new A();110 delete a;111}112 113// CHECK-LABEL: void test_deleteArraydtor()114// CHECK: [B2 (ENTRY)]115// CHECK-NEXT: Succs (1): B1116// CHECK: [B1]117// CHECK-NEXT: 1: 5118// CHECK-NEXT: 2: CFGNewAllocator(A *)119// WARNINGS-NEXT: 3: (CXXConstructExpr, A[5])120// ANALYZER-NEXT: 3: (CXXConstructExpr, [B1.4], A[5])121// CHECK-NEXT: 4: new A {{\[\[}}B1.1]]122// CHECK-NEXT: 5: A *a = new A [5];123// CHECK-NEXT: 6: a124// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, A *)125// CHECK-NEXT: 8: [B1.7]->~A() (Implicit destructor)126// CHECK-NEXT: 9: delete [] [B1.7]127// CHECK-NEXT: Preds (1): B2128// CHECK-NEXT: Succs (1): B0129// CHECK: [B0 (EXIT)]130// CHECK-NEXT: Preds (1): B1131void test_deleteArraydtor() {132 A *a = new A[5];133 delete[] a;134}135 136 137namespace NoReturnSingleSuccessor {138 struct A {139 A();140 ~A();141 };142 143 struct B : public A {144 B();145 ~B() __attribute__((noreturn));146 };147 148// CHECK-LABEL: int test1(int *x)149// CHECK: 1: 1150// CHECK-NEXT: 2: return151// CHECK-NEXT: ~B() (Implicit destructor)152// CHECK-NEXT: Preds (1)153// CHECK-NEXT: Succs (1): B0154 int test1(int *x) {155 B b;156 if (x)157 return 1;158 }159 160// CHECK-LABEL: int test2(int *x)161// CHECK: 1: 1162// CHECK-NEXT: 2: return163// CHECK-NEXT: destructor164// CHECK-NEXT: Preds (1)165// CHECK-NEXT: Succs (1): B0166 int test2(int *x) {167 const A& a = B();168 if (x)169 return 1;170 }171}172 173// Test CFG support for "extending" an enum.174// CHECK-LABEL: int test_enum_with_extension(enum MyEnum value)175// CHECK: [B7 (ENTRY)]176// CHECK-NEXT: Succs (1): B2177// CHECK: [B1]178// CHECK-NEXT: 1: x179// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)180// CHECK-NEXT: 3: return [B1.2];181// CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable)182// CHECK-NEXT: Succs (1): B0183// CHECK: [B2]184// CHECK-NEXT: 1: 0185// CHECK-NEXT: 2: int x = 0;186// CHECK-NEXT: 3: value187// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)188// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int)189// CHECK-NEXT: T: switch [B2.5]190// CHECK-NEXT: Preds (1): B7191// CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable)192// CHECK: [B3]193// CHECK-NEXT: case D:194// CHECK-NEXT: 1: 4195// CHECK-NEXT: 2: x196// CHECK-NEXT: 3: [B3.2] = [B3.1]197// CHECK-NEXT: T: break;198// CHECK-NEXT: Preds (1): B2199// CHECK-NEXT: Succs (1): B1200// CHECK: [B4]201// CHECK-NEXT: case C:202// CHECK-NEXT: 1: 3203// CHECK-NEXT: 2: x204// CHECK-NEXT: 3: [B4.2] = [B4.1]205// CHECK-NEXT: T: break;206// CHECK-NEXT: Preds (1): B2207// CHECK-NEXT: Succs (1): B1208// CHECK: [B5]209// CHECK-NEXT: case B:210// CHECK-NEXT: 1: 2211// CHECK-NEXT: 2: x212// CHECK-NEXT: 3: [B5.2] = [B5.1]213// CHECK-NEXT: T: break;214// CHECK-NEXT: Preds (1): B2215// CHECK-NEXT: Succs (1): B1216// CHECK: [B6]217// CHECK-NEXT: case A:218// CHECK-NEXT: 1: 1219// CHECK-NEXT: 2: x220// CHECK-NEXT: 3: [B6.2] = [B6.1]221// CHECK-NEXT: T: break;222// CHECK-NEXT: Preds (1): B2223// CHECK-NEXT: Succs (1): B1224// CHECK: [B0 (EXIT)]225// CHECK-NEXT: Preds (1): B1226enum MyEnum : int { A, B, C };227static const enum MyEnum D = (enum MyEnum) 32;228 229int test_enum_with_extension(enum MyEnum value) {230 int x = 0;231 switch (value) {232 case A: x = 1; break;233 case B: x = 2; break;234 case C: x = 3; break;235 case D: x = 4; break;236 }237 return x;238}239 240// CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value)241// CHECK: [B7 (ENTRY)]242// CHECK-NEXT: Succs (1): B2243// CHECK: [B1]244// CHECK-NEXT: 1: x245// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)246// CHECK-NEXT: 3: return [B1.2];247// CHECK-NEXT: Preds (4): B3 B4 B5 B6248// CHECK-NEXT: Succs (1): B0249// CHECK: [B2]250// CHECK-NEXT: 1: 0251// CHECK-NEXT: 2: int x = 0;252// CHECK-NEXT: 3: value253// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)254// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int)255// CHECK-NEXT: T: switch [B2.5]256// CHECK-NEXT: Preds (1): B7257// CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable)258// CHECK: [B3]259// CHECK-NEXT: default:260// CHECK-NEXT: 1: 4261// CHECK-NEXT: 2: x262// CHECK-NEXT: 3: [B3.2] = [B3.1]263// CHECK-NEXT: T: break;264// CHECK-NEXT: Preds (1): B2(Unreachable)265// CHECK-NEXT: Succs (1): B1266// CHECK: [B4]267// CHECK-NEXT: case C:268// CHECK-NEXT: 1: 3269// CHECK-NEXT: 2: x270// CHECK-NEXT: 3: [B4.2] = [B4.1]271// CHECK-NEXT: T: break;272// CHECK-NEXT: Preds (1): B2273// CHECK-NEXT: Succs (1): B1274// CHECK: [B5]275// CHECK-NEXT: case B:276// CHECK-NEXT: 1: 2277// CHECK-NEXT: 2: x278// CHECK-NEXT: 3: [B5.2] = [B5.1]279// CHECK-NEXT: T: break;280// CHECK-NEXT: Preds (1): B2281// CHECK-NEXT: Succs (1): B1282// CHECK: [B6]283// CHECK-NEXT: case A:284// CHECK-NEXT: 1: 1285// CHECK-NEXT: 2: x286// CHECK-NEXT: 3: [B6.2] = [B6.1]287// CHECK-NEXT: T: break;288// CHECK-NEXT: Preds (1): B2289// CHECK-NEXT: Succs (1): B1290// CHECK: [B0 (EXIT)]291// CHECK-NEXT: Preds (1): B1292int test_enum_with_extension_default(enum MyEnum value) {293 int x = 0;294 switch (value) {295 case A: x = 1; break;296 case B: x = 2; break;297 case C: x = 3; break;298 default: x = 4; break;299 }300 return x;301}302 303// CHECK-LABEL: void test_placement_new()304// CHECK: [B2 (ENTRY)]305// CHECK-NEXT: Succs (1): B1306// CHECK: [B1]307// CHECK-NEXT: 1: int buffer[16];308// CHECK-NEXT: 2: buffer309// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)310// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *)311// CHECK-NEXT: 5: CFGNewAllocator(MyClass *)312// WARNINGS-NEXT: 6: (CXXConstructExpr, MyClass)313// ANALYZER-NEXT: 6: (CXXConstructExpr, [B1.7], MyClass)314// CHECK-NEXT: 7: new ([B1.4]) MyClass([B1.6])315// CHECK-NEXT: 8: MyClass *obj = new (buffer) MyClass();316// CHECK-NEXT: Preds (1): B2317// CHECK-NEXT: Succs (1): B0318// CHECK: [B0 (EXIT)]319// CHECK-NEXT: Preds (1): B1320 321extern void* operator new (unsigned long sz, void* v);322extern void* operator new[] (unsigned long sz, void* ptr);323 324class MyClass {325public:326 MyClass() {}327 ~MyClass() {}328};329 330void test_placement_new() {331 int buffer[16];332 MyClass* obj = new (buffer) MyClass();333}334 335// CHECK-LABEL: void test_placement_new_array()336// CHECK: [B2 (ENTRY)]337// CHECK-NEXT: Succs (1): B1338// CHECK: [B1]339// CHECK-NEXT: 1: int buffer[16];340// CHECK-NEXT: 2: buffer341// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)342// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *)343// CHECK-NEXT: 5: 5344// CHECK-NEXT: 6: CFGNewAllocator(MyClass *)345// WARNINGS-NEXT: 7: (CXXConstructExpr, MyClass[5])346// ANALYZER-NEXT: 7: (CXXConstructExpr, [B1.8], MyClass[5])347// CHECK-NEXT: 8: new ([B1.4]) MyClass {{\[\[}}B1.5]]348// CHECK-NEXT: 9: MyClass *obj = new (buffer) MyClass [5];349// CHECK-NEXT: Preds (1): B2350// CHECK-NEXT: Succs (1): B0351// CHECK: [B0 (EXIT)]352// CHECK-NEXT: Preds (1): B1353 354void test_placement_new_array() {355 int buffer[16];356 MyClass* obj = new (buffer) MyClass[5];357}358 359 360// CHECK-LABEL: void test_lifetime_extended_temporaries()361// CHECK: [B1]362struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); };363struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; };364struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; };365void test_lifetime_extended_temporaries() {366 // CHECK: LifetimeExtend(1);367 // CHECK-NEXT: : 1368 // CHECK-NEXT: ~LifetimeExtend()369 // CHECK-NOT: ~LifetimeExtend()370 {371 const LifetimeExtend &l = LifetimeExtend(1);372 1;373 }374 // CHECK: LifetimeExtend(2)375 // CHECK-NEXT: ~LifetimeExtend()376 // CHECK-NEXT: : 2377 // CHECK-NOT: ~LifetimeExtend()378 {379 // No life-time extension.380 const int &l = (LifetimeExtend(2), 2);381 2;382 }383 // CHECK: LifetimeExtend(3)384 // CHECK-NEXT: : 3385 // CHECK-NEXT: ~LifetimeExtend()386 // CHECK-NOT: ~LifetimeExtend()387 {388 // The last one is lifetime extended.389 const LifetimeExtend &l = (3, LifetimeExtend(3));390 3;391 }392 // CHECK: LifetimeExtend(4)393 // CHECK-NEXT: ~LifetimeExtend()394 // CHECK-NEXT: ~LifetimeExtend()395 // CHECK-NEXT: : 4396 // CHECK-NOT: ~LifetimeExtend()397 {398 Aggregate a{LifetimeExtend(4), LifetimeExtend(4)};399 4;400 }401 // CHECK: LifetimeExtend(5)402 // CHECK-NEXT: : 5403 // FIXME: We want to emit the destructors of the lifetime404 // extended variables here.405 // CHECK-NOT: ~LifetimeExtend()406 {407 AggregateRef a{LifetimeExtend(5), LifetimeExtend(5)};408 5;409 }410 // FIXME: Add tests for lifetime extension via subobject411 // references (LifetimeExtend().some_member).412}413 414 415// FIXME: The destructor for 'a' shouldn't be there because it's deleted416// in the union.417// CHECK-LABEL: void foo()418// CHECK: [B2 (ENTRY)]419// CHECK-NEXT: Succs (1): B1420// CHECK: [B1]421// WARNINGS-NEXT: 1: (CXXConstructExpr, A)422// ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], A)423// CHECK-NEXT: 2: A a;424// CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor)425// CHECK-NEXT: Preds (1): B2426// CHECK-NEXT: Succs (1): B0427// CHECK: [B0 (EXIT)]428// CHECK-NEXT: Preds (1): B1429 430namespace pr37688_deleted_union_destructor {431struct S { ~S(); };432struct A {433 ~A() noexcept {}434 union {435 struct {436 S s;437 } ss;438 };439};440void foo() {441 A a;442}443} // end namespace pr37688_deleted_union_destructor444 445 446namespace return_statement_expression {447int unknown();448 449// CHECK-LABEL: int foo()450// CHECK: [B6 (ENTRY)]451// CHECK-NEXT: Succs (1): B5452// CHECK: [B1]453// CHECK-NEXT: 1: 0454// CHECK-NEXT: 2: return [B1.1];455// CHECK-NEXT: Preds (1): B5456// CHECK-NEXT: Succs (1): B0457// CHECK: [B2]458// CHECK-NEXT: 1: 0459// CHECK-NEXT: 2: ({ ... ; [B2.1] })460// CHECK-NEXT: 3: return [B2.2];461// CHECK-NEXT: Preds (1): B4462// CHECK-NEXT: Succs (1): B0463// FIXME: Why do we have [B3] at all?464// CHECK: [B3]465// CHECK-NEXT: Succs (1): B4466// CHECK: [B4]467// CHECK-NEXT: 1: 0468// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, IntegralToBoolean, _Bool)469// CHECK-NEXT: T: while [B4.2]470// CHECK-NEXT: Preds (2): B3 B5471// CHECK-NEXT: Succs (2): NULL B2472// CHECK: [B5]473// CHECK-NEXT: 1: unknown474// CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void))475// CHECK-NEXT: 3: [B5.2]()476// CHECK-NEXT: 4: [B5.3] (ImplicitCastExpr, IntegralToBoolean, _Bool)477// CHECK-NEXT: T: if [B5.4]478// CHECK-NEXT: Preds (1): B6479// CHECK-NEXT: Succs (2): B4 B1480// CHECK: [B0 (EXIT)]481// CHECK-NEXT: Preds (2): B1 B2482int foo() {483 if (unknown())484 return ({485 while (0)486 ;487 0;488 });489 else490 return 0;491}492} // namespace statement_expression_in_return493 494// CHECK-LABEL: void vla_simple(int x)495// CHECK: [B1]496// CHECK-NEXT: 1: x497// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)498// CHECK-NEXT: 3: int vla[x];499void vla_simple(int x) {500 int vla[x];501}502 503// CHECK-LABEL: void vla_typedef(int x)504// CHECK: [B1]505// CHECK-NEXT: 1: x506// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)507// CHECK-NEXT: 3: typedef int VLA[x];508void vla_typedef(int x) {509 typedef int VLA[x];510}511 512// CHECK-LABEL: void vla_typealias(int x)513// CHECK: [B1]514// CHECK-NEXT: 1: x515// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)516// CHECK-NEXT: 3: using VLA = int[x];517void vla_typealias(int x) {518 using VLA = int[x];519}520 521// CHECK-LABEL: void vla_typedef_multi(int x, int y)522// CHECK: [B1]523// CHECK-NEXT: 1: y524// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)525// CHECK-NEXT: 3: x526// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, LValueToRValue, int)527// CHECK-NEXT: 5: typedef int VLA[x][y];528void vla_typedef_multi(int x, int y) {529 typedef int VLA[x][y];530}531 532// CHECK-LABEL: void vla_typedefname_multi(int x, int y)533// CHECK: [B1]534// CHECK-NEXT: 1: x535// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)536// CHECK-NEXT: 3: typedef int VLA[x];537// CHECK-NEXT: 4: y538// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, int)539// CHECK-NEXT: 6: typedef VLA VLA1[y];540// CHECK-NEXT: 7: 3541// CHECK-NEXT: 8: using VLA2 = VLA1[3];542// CHECK-NEXT: 9: 4543// CHECK-NEXT: 10: VLA2 vla[4];544void vla_typedefname_multi(int x, int y) {545 typedef int VLA[x];546 typedef VLA VLA1[y];547 using VLA2 = VLA1[3];548 VLA2 vla[4];549}550 551// CHECK-LABEL: int vla_evaluate(int x)552// CHECK: [B1]553// CHECK-NEXT: 1: x554// CHECK-NEXT: 2: ++[B1.1]555// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, LValueToRValue, int)556// CHECK-NEXT: 4: typedef int VLA[++x];557// CHECK-NEXT: 5: x558// CHECK-NEXT: 6: ++[B1.5]559// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, int)560// CHECK-NEXT: 8: sizeof(int[++x])561// CHECK-NEXT: 9: alignof(int[++x])562// CHECK-NEXT: 10: 0563// CHECK-NEXT: 11: x564// CHECK-NEXT: 12: [B1.11] (ImplicitCastExpr, LValueToRValue, int)565// CHECK-NEXT: 13: return [B1.12];566int vla_evaluate(int x) {567 // Evaluates the ++x568 typedef int VLA[++x];569 sizeof(int[++x]);570 571 // Do not evaluate the ++x572 _Alignof(int[++x]);573 _Generic((int(*)[++x])0, default : 0);574 575 return x;576}577 578// CHECK-LABEL: void CommaTemp::f()579// CHECK: [B1]580// CHECK-NEXT: 1: A() (CXXConstructExpr,581// CHECK-NEXT: 2: [B1.1] (BindTemporary)582// CHECK-NEXT: 3: B() (CXXConstructExpr,583// CHECK-NEXT: 4: [B1.3] (BindTemporary)584// CHECK-NEXT: 5: ... , [B1.4]585// CHECK-NEXT: 6: ~B() (Temporary object destructor)586// CHECK-NEXT: 7: ~A() (Temporary object destructor)587namespace CommaTemp {588 struct A { ~A(); };589 struct B { ~B(); };590 void f();591}592void CommaTemp::f() {593 A(), B();594}595 596// CHECK-LABEL: int crash_with_thread_local(char *p, int *q)597// CHECK: [B7 (ENTRY)]598// CHECK-NEXT: Succs (1): B6599// CHECK: [B1]600// CHECK-NEXT: bail:601// CHECK-NEXT: 1: 0602// CHECK-NEXT: 2: return [B1.1];603// CHECK-NEXT: Preds (2): B2 B5604// CHECK-NEXT: Succs (1): B0605// CHECK: [B2]606// CHECK-NEXT: 1: 0607// CHECK-NEXT: 2: q608// CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, LValueToRValue, int *)609// CHECK-NEXT: 4: *[B2.3]610// CHECK-NEXT: 5: [B2.4] = [B2.1]611// CHECK-NEXT: Preds (2): B3 B4612// CHECK-NEXT: Succs (1): B1613// CHECK: [B3]614// WARNINGS-NEXT: 1: (CXXConstructExpr, ClassWithDtor)615// ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], ClassWithDtor)616// CHECK-NEXT: 2: thread_local ClassWithDtor a;617// CHECK-NEXT: Preds (1): B4618// CHECK-NEXT: Succs (1): B2619// CHECK: [B4]620// CHECK-NEXT: T: static init a621// CHECK-NEXT: Preds (1): B6622// CHECK-NEXT: Succs (2): B2 B3623// CHECK: [B5]624// CHECK-NEXT: T: goto bail;625// CHECK-NEXT: Preds (1): B6626// CHECK-NEXT: Succs (1): B1627// CHECK: [B6]628// CHECK-NEXT: 1: p629// CHECK-NEXT: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, char *)630// CHECK-NEXT: 3: 0631// CHECK-NEXT: 4: [B6.3] (ImplicitCastExpr, NullToPointer, char *)632// CHECK-NEXT: 5: [B6.2] != [B6.4]633// CHECK-NEXT: T: if [B6.5]634// CHECK-NEXT: Preds (1): B7635// CHECK-NEXT: Succs (2): B5 B4636// CHECK: [B0 (EXIT)]637// CHECK-NEXT: Preds (1): B1638 639struct ClassWithDtor {640 ~ClassWithDtor() {}641};642 643int crash_with_thread_local(char *p, int *q) {644 if (p != 0) {645 goto bail;646 }647 thread_local ClassWithDtor a;648 *q = 0;649bail:650 return 0;651}652 653// CHECK-LABEL: void DecompositionDecl()654// CHECK: [B1]655// CHECK-NEXT: 1: int arr[2];656// CHECK-NEXT: 2: arr657// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)658// CHECK-NEXT: 4: *659// CHECK-NEXT: 5: [B1.3]{{\[\[}}B1.4]]660// CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, int)661// CHECK-NEXT: 7: {{\{}}[B1.6]{{(\})}}662// CHECK-NEXT: 8: auto = {{\{}}arr[*]{{(\})}};663void DecompositionDecl() {664 int arr[2];665 666 auto [a, b] = arr;667}668 669// CHECK-LABEL: template<> int *PR18472<int>()670// CHECK: [B2 (ENTRY)]671// CHECK-NEXT: Succs (1): B1672// CHECK: [B1]673// CHECK-NEXT: 1: 0674// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t)675// CHECK-NEXT: 3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t)676// CHECK-NEXT: 4: CFGNewAllocator(int *)677// CHECK-NEXT: 5: new (([B1.3])) int678// CHECK-NEXT: 6: return [B1.5];679// CHECK-NEXT: Preds (1): B2680// CHECK-NEXT: Succs (1): B0681// CHECK: [B0 (EXIT)]682// CHECK-NEXT: Preds (1): B1683 684extern "C" typedef int *PR18472_t;685void *operator new (unsigned long, PR18472_t);686template <class T> T *PR18472() {687 return new (((PR18472_t) 0)) T;688}689void PR18472_helper() {690 PR18472<int>();691}692