295 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=false %s 2>&1 | FileCheck -check-prefixes=CHECK,WARNINGS %s2// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=true %s 2>&1 | FileCheck -check-prefixes=CHECK,ANALYZER %s3 4// This file tests how we construct two different flavors of the Clang CFG -5// the CFG used by the Sema analysis-based warnings and the CFG used by the6// static analyzer. The difference in the behavior is checked via FileCheck7// prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer8// flags, no new run lines should be added - just these flags would go to the9// respective line depending on where is it turned on and where is it turned10// off. Feel free to add tests that test only one of the CFG flavors if you're11// not sure how the other flavor is supposed to work in your case.12 13class A {14public:15 // CHECK: A()16 // CHECK: [B1 (ENTRY)]17 // CHECK-NEXT: Succs (1): B018 // CHECK: [B0 (EXIT)]19 // CHECK-NEXT: Preds (1): B120 A() {}21 22 // CHECK: A(int i)23 // CHECK: [B1 (ENTRY)]24 // CHECK-NEXT: Succs (1): B025 // CHECK: [B0 (EXIT)]26 // CHECK-NEXT: Preds (1): B127 A(int i) {}28};29 30class B : public virtual A {31public:32 // CHECK: B()33 // CHECK: [B3 (ENTRY)]34 // CHECK-NEXT: Succs (1): B235 // CHECK: [B1]36 // WARNINGS-NEXT: 1: (CXXConstructExpr, A)37 // ANALYZER-NEXT: 1: (CXXConstructExpr, A() (Base initializer), A)38 // CHECK-NEXT: 2: A([B1.1]) (Base initializer)39 // CHECK-NEXT: Preds (1): B240 // CHECK-NEXT: Succs (1): B041 // CHECK: [B2]42 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases)43 // CHECK-NEXT: Preds (1): B344 // CHECK-NEXT: Succs (2): B0 B145 // CHECK: [B0 (EXIT)]46 // CHECK-NEXT: Preds (2): B1 B247 B() {}48 49 // CHECK: B(int i)50 // CHECK: [B3 (ENTRY)]51 // CHECK-NEXT: Succs (1): B252 // CHECK: [B1]53 // CHECK-NEXT: 1: i54 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)55 // WARNINGS-NEXT: 3: [B1.2] (CXXConstructExpr, A)56 // ANALYZER-NEXT: 3: [B1.2] (CXXConstructExpr, A([B1.2]) (Base initializer), A)57 // CHECK-NEXT: 4: A([B1.3]) (Base initializer)58 // CHECK-NEXT: Preds (1): B259 // CHECK-NEXT: Succs (1): B060 // CHECK: [B2]61 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases)62 // CHECK-NEXT: Preds (1): B363 // CHECK-NEXT: Succs (2): B0 B164 // CHECK: [B0 (EXIT)]65 // CHECK-NEXT: Preds (2): B1 B266 B(int i) : A(i) {}67};68 69class C : public virtual A {70public:71 // CHECK: C()72 // CHECK: [B3 (ENTRY)]73 // CHECK-NEXT: Succs (1): B274 // CHECK: [B1]75 // WARNINGS-NEXT: 1: (CXXConstructExpr, A)76 // ANALYZER-NEXT: 1: (CXXConstructExpr, A() (Base initializer), A)77 // CHECK-NEXT: 2: A([B1.1]) (Base initializer)78 // CHECK-NEXT: Preds (1): B279 // CHECK-NEXT: Succs (1): B080 // CHECK: [B2]81 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases)82 // CHECK-NEXT: Preds (1): B383 // CHECK-NEXT: Succs (2): B0 B184 // CHECK: [B0 (EXIT)]85 // CHECK-NEXT: Preds (2): B1 B286 C() {}87 88 // CHECK: C(int i)89 // CHECK: [B3 (ENTRY)]90 // CHECK-NEXT: Succs (1): B291 // CHECK: [B1]92 // CHECK-NEXT: 1: i93 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)94 // WARNINGS-NEXT: 3: [B1.2] (CXXConstructExpr, A)95 // ANALYZER-NEXT: 3: [B1.2] (CXXConstructExpr, A([B1.2]) (Base initializer), A)96 // CHECK-NEXT: 4: A([B1.3]) (Base initializer)97 // CHECK-NEXT: Preds (1): B298 // CHECK-NEXT: Succs (1): B099 // CHECK: [B2]100 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases)101 // CHECK-NEXT: Preds (1): B3102 // CHECK-NEXT: Succs (2): B0 B1103 // CHECK: [B0 (EXIT)]104 // CHECK-NEXT: Preds (2): B1 B2105 C(int i) : A(i) {}106};107 108 109class TestOrder : public C, public B, public A {110 int i;111 int& r;112public:113 TestOrder();114};115 116// CHECK: TestOrder::TestOrder()117// CHECK: [B4 (ENTRY)]118// CHECK-NEXT: Succs (1): B3119// CHECK: [B1]120// WARNINGS-NEXT: 1: (CXXConstructExpr, C)121// ANALYZER-NEXT: 1: (CXXConstructExpr, C() (Base initializer), C)122// CHECK-NEXT: 2: C([B1.1]) (Base initializer)123// WARNINGS-NEXT: 3: (CXXConstructExpr, B)124// ANALYZER-NEXT: 3: (CXXConstructExpr, B() (Base initializer), B)125// CHECK-NEXT: 4: B([B1.3]) (Base initializer)126// WARNINGS-NEXT: 5: (CXXConstructExpr, A)127// ANALYZER-NEXT: 5: (CXXConstructExpr, A() (Base initializer), A)128// CHECK-NEXT: 6: A([B1.5]) (Base initializer)129// CHECK-NEXT: 7: i(/*implicit*/(int)0) (Member initializer)130// CHECK-NEXT: 8: this131// CHECK-NEXT: 9: [B1.8]->i132// CHECK-NEXT: 10: r([B1.9]) (Member initializer)133// WARNINGS-NEXT: 11: (CXXConstructExpr, A)134// ANALYZER-NEXT: 11: (CXXConstructExpr, [B1.12], A)135// CHECK-NEXT: 12: A a;136// CHECK-NEXT: Preds (2): B2 B3137// CHECK-NEXT: Succs (1): B0138// CHECK: [B2]139// WARNINGS-NEXT: 1: (CXXConstructExpr, A)140// ANALYZER-NEXT: 1: (CXXConstructExpr, A() (Base initializer), A)141// CHECK-NEXT: 2: A([B2.1]) (Base initializer)142// CHECK-NEXT: Preds (1): B3143// CHECK-NEXT: Succs (1): B1144// CHECK: [B3]145// CHECK-NEXT: T: (See if most derived ctor has already initialized vbases)146// CHECK-NEXT: Preds (1): B4147// CHECK-NEXT: Succs (2): B1 B2148// CHECK: [B0 (EXIT)]149// CHECK-NEXT: Preds (1): B1150TestOrder::TestOrder()151 : r(i), B(), i(), C() {152 A a;153}154 155class TestControlFlow {156 int x, y, z;157public:158 TestControlFlow(bool b);159};160 161// CHECK: TestControlFlow::TestControlFlow(bool b)162// CHECK: [B5 (ENTRY)]163// CHECK-NEXT: Succs (1): B4164// CHECK: [B1]165// CHECK-NEXT: 1: [B4.4] ? [B2.1] : [B3.1]166// CHECK-NEXT: 2: y([B1.1]) (Member initializer)167// CHECK-NEXT: 3: this168// CHECK-NEXT: 4: [B1.3]->y169// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, int)170// CHECK-NEXT: 6: z([B1.5]) (Member initializer)171// CHECK-NEXT: 7: int v;172// CHECK-NEXT: Preds (2): B2 B3173// CHECK-NEXT: Succs (1): B0174// CHECK: [B2]175// CHECK-NEXT: 1: 0176// CHECK-NEXT: Preds (1): B4177// CHECK-NEXT: Succs (1): B1178// CHECK: [B3]179// CHECK-NEXT: 1: 1180// CHECK-NEXT: Preds (1): B4181// CHECK-NEXT: Succs (1): B1182// CHECK: [B4]183// CHECK-NEXT: 1: 0184// CHECK-NEXT: 2: x([B4.1]) (Member initializer)185// CHECK-NEXT: 3: b186// CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool)187// CHECK-NEXT: T: [B4.4] ? ... : ...188// CHECK-NEXT: Preds (1): B5189// CHECK-NEXT: Succs (2): B2 B3190// CHECK: [B0 (EXIT)]191// CHECK-NEXT: Preds (1): B1192TestControlFlow::TestControlFlow(bool b)193 : y(b ? 0 : 1)194 , x(0)195 , z(y) {196 int v;197}198 199class TestDelegating {200 int x, z;201public:202 203 // CHECK: TestDelegating()204 // CHECK: [B2 (ENTRY)]205 // CHECK-NEXT: Succs (1): B1206 // CHECK: [B1]207 // CHECK-NEXT: 1: 2208 // CHECK-NEXT: 2: 3209 // WARNINGS-NEXT: 3: [B1.1], [B1.2] (CXXConstructExpr, class TestDelegating)210 // ANALYZER-NEXT: 3: [B1.1], [B1.2] (CXXConstructExpr, TestDelegating([B1.1], [B1.2]) (Delegating initializer), class TestDelegating)211 // CHECK-NEXT: 4: TestDelegating([B1.3]) (Delegating initializer)212 // CHECK-NEXT: Preds (1): B2213 // CHECK-NEXT: Succs (1): B0214 // CHECK: [B0 (EXIT)]215 // CHECK-NEXT: Preds (1): B1216 TestDelegating() : TestDelegating(2, 3) {}217 218 // CHECK: TestDelegating(int x, int z)219 // CHECK: [B2 (ENTRY)]220 // CHECK-NEXT: Succs (1): B1221 // CHECK: [B1]222 // CHECK-NEXT: 1: x223 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)224 // CHECK-NEXT: 3: x([B1.2]) (Member initializer)225 // CHECK-NEXT: 4: z226 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, int)227 // CHECK-NEXT: 6: z([B1.5]) (Member initializer)228 // CHECK-NEXT: Preds (1): B2229 // CHECK-NEXT: Succs (1): B0230 // CHECK: [B0 (EXIT)]231 // CHECK-NEXT: Preds (1): B1232 TestDelegating(int x, int z) : x(x), z(z) {}233};234 235class TestMoreControlFlow : public virtual A {236 A a;237 238public:239 TestMoreControlFlow(bool coin);240};241 242// CHECK: TestMoreControlFlow::TestMoreControlFlow(bool coin)243// CHECK: [B10 (ENTRY)]244// CHECK-NEXT: Succs (1): B9245// CHECK: [B1]246// CHECK-NEXT: 1: [B4.2] ? [B2.1] : [B3.1]247// WARNINGS-NEXT: 2: [B1.1] (CXXConstructExpr, A)248// ANALYZER-NEXT: 2: [B1.1] (CXXConstructExpr, a([B1.1]) (Member initializer), A)249// CHECK-NEXT: 3: a([B1.2]) (Member initializer)250// CHECK-NEXT: Preds (2): B2 B3251// CHECK-NEXT: Succs (1): B0252// CHECK: [B2]253// CHECK-NEXT: 1: 3254// CHECK-NEXT: Preds (1): B4255// CHECK-NEXT: Succs (1): B1256// CHECK: [B3]257// CHECK-NEXT: 1: 4258// CHECK-NEXT: Preds (1): B4259// CHECK-NEXT: Succs (1): B1260// CHECK: [B4]261// CHECK-NEXT: 1: coin262// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)263// CHECK-NEXT: T: [B4.2] ? ... : ...264// CHECK-NEXT: Preds (2): B5 B9265// CHECK-NEXT: Succs (2): B2 B3266// CHECK: [B5]267// CHECK-NEXT: 1: [B8.2] ? [B6.1] : [B7.1]268// WARNINGS-NEXT: 2: [B5.1] (CXXConstructExpr, A)269// ANALYZER-NEXT: 2: [B5.1] (CXXConstructExpr, A([B5.1]) (Base initializer), A)270// CHECK-NEXT: 3: A([B5.2]) (Base initializer)271// CHECK-NEXT: Preds (2): B6 B7272// CHECK-NEXT: Succs (1): B4273// CHECK: [B6]274// CHECK-NEXT: 1: 1275// CHECK-NEXT: Preds (1): B8276// CHECK-NEXT: Succs (1): B5277// CHECK: [B7]278// CHECK-NEXT: 1: 2279// CHECK-NEXT: Preds (1): B8280// CHECK-NEXT: Succs (1): B5281// CHECK: [B8]282// CHECK-NEXT: 1: coin283// CHECK-NEXT: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool)284// CHECK-NEXT: T: [B8.2] ? ... : ...285// CHECK-NEXT: Preds (1): B9286// CHECK-NEXT: Succs (2): B6 B7287// CHECK: [B9]288// CHECK-NEXT: T: (See if most derived ctor has already initialized vbases)289// CHECK-NEXT: Preds (1): B10290// CHECK-NEXT: Succs (2): B4 B8291// CHECK: [B0 (EXIT)]292// CHECK-NEXT: Preds (1): B1293TestMoreControlFlow::TestMoreControlFlow(bool coin)294 : A(coin ? 1 : 2), a(coin ? 3 : 4) {}295