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 %s 2 // 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 %s 3 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 the 6 // static analyzer. The difference in the behavior is checked via FileCheck 7 // prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer 8 // flags, no new run lines should be added - just these flags would go to the 9 // respective line depending on where is it turned on and where is it turned 10 // off. Feel free to add tests that test only one of the CFG flavors if you're 11 // not sure how the other flavor is supposed to work in your case. 12 13 class A { 14 public: 15 // CHECK: A() 16 // CHECK: [B1 (ENTRY)] 17 // CHECK-NEXT: Succs (1): B0 18 // CHECK: [B0 (EXIT)] 19 // CHECK-NEXT: Preds (1): B1 20 A() {} 21 22 // CHECK: A(int i) 23 // CHECK: [B1 (ENTRY)] 24 // CHECK-NEXT: Succs (1): B0 25 // CHECK: [B0 (EXIT)] 26 // CHECK-NEXT: Preds (1): B1 27 A(int i) {} 28 }; 29 30 class B : public virtual A { 31 public: 32 // CHECK: B() 33 // CHECK: [B3 (ENTRY)] 34 // CHECK-NEXT: Succs (1): B2 35 // CHECK: [B1] 36 // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) 37 // ANALYZER-NEXT: 1: (CXXConstructExpr, A() (Base initializer), class A) 38 // CHECK-NEXT: 2: A([B1.1]) (Base initializer) 39 // CHECK-NEXT: Preds (1): B2 40 // CHECK-NEXT: Succs (1): B0 41 // CHECK: [B2] 42 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 43 // CHECK-NEXT: Preds (1): B3 44 // CHECK-NEXT: Succs (2): B0 B1 45 // CHECK: [B0 (EXIT)] 46 // CHECK-NEXT: Preds (2): B1 B2 47 B() {} 48 49 // CHECK: B(int i) 50 // CHECK: [B3 (ENTRY)] 51 // CHECK-NEXT: Succs (1): B2 52 // CHECK: [B1] 53 // CHECK-NEXT: 1: i 54 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 55 // WARNINGS-NEXT: 3: [B1.2] (CXXConstructExpr, class A) 56 // ANALYZER-NEXT: 3: [B1.2] (CXXConstructExpr, A([B1.2]) (Base initializer), class A) 57 // CHECK-NEXT: 4: A([B1.3]) (Base initializer) 58 // CHECK-NEXT: Preds (1): B2 59 // CHECK-NEXT: Succs (1): B0 60 // CHECK: [B2] 61 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 62 // CHECK-NEXT: Preds (1): B3 63 // CHECK-NEXT: Succs (2): B0 B1 64 // CHECK: [B0 (EXIT)] 65 // CHECK-NEXT: Preds (2): B1 B2 66 B(int i) : A(i) {} 67 }; 68 69 class C : public virtual A { 70 public: 71 // CHECK: C() 72 // CHECK: [B3 (ENTRY)] 73 // CHECK-NEXT: Succs (1): B2 74 // CHECK: [B1] 75 // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) 76 // ANALYZER-NEXT: 1: (CXXConstructExpr, A() (Base initializer), class A) 77 // CHECK-NEXT: 2: A([B1.1]) (Base initializer) 78 // CHECK-NEXT: Preds (1): B2 79 // CHECK-NEXT: Succs (1): B0 80 // CHECK: [B2] 81 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 82 // CHECK-NEXT: Preds (1): B3 83 // CHECK-NEXT: Succs (2): B0 B1 84 // CHECK: [B0 (EXIT)] 85 // CHECK-NEXT: Preds (2): B1 B2 86 C() {} 87 88 // CHECK: C(int i) 89 // CHECK: [B3 (ENTRY)] 90 // CHECK-NEXT: Succs (1): B2 91 // CHECK: [B1] 92 // CHECK-NEXT: 1: i 93 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 94 // WARNINGS-NEXT: 3: [B1.2] (CXXConstructExpr, class A) 95 // ANALYZER-NEXT: 3: [B1.2] (CXXConstructExpr, A([B1.2]) (Base initializer), class A) 96 // CHECK-NEXT: 4: A([B1.3]) (Base initializer) 97 // CHECK-NEXT: Preds (1): B2 98 // CHECK-NEXT: Succs (1): B0 99 // CHECK: [B2] 100 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 101 // CHECK-NEXT: Preds (1): B3 102 // CHECK-NEXT: Succs (2): B0 B1 103 // CHECK: [B0 (EXIT)] 104 // CHECK-NEXT: Preds (2): B1 B2 105 C(int i) : A(i) {} 106 }; 107 108 109 class TestOrder : public C, public B, public A { 110 int i; 111 int& r; 112 public: 113 TestOrder(); 114 }; 115 116 // CHECK: TestOrder::TestOrder() 117 // CHECK: [B4 (ENTRY)] 118 // CHECK-NEXT: Succs (1): B3 119 // CHECK: [B1] 120 // WARNINGS-NEXT: 1: (CXXConstructExpr, class C) 121 // ANALYZER-NEXT: 1: (CXXConstructExpr, C() (Base initializer), class C) 122 // CHECK-NEXT: 2: C([B1.1]) (Base initializer) 123 // WARNINGS-NEXT: 3: (CXXConstructExpr, class B) 124 // ANALYZER-NEXT: 3: (CXXConstructExpr, B() (Base initializer), class B) 125 // CHECK-NEXT: 4: B([B1.3]) (Base initializer) 126 // WARNINGS-NEXT: 5: (CXXConstructExpr, class A) 127 // ANALYZER-NEXT: 5: (CXXConstructExpr, A() (Base initializer), class A) 128 // CHECK-NEXT: 6: A([B1.5]) (Base initializer) 129 // CHECK-NEXT: 7: i(/*implicit*/(int)0) (Member initializer) 130 // CHECK-NEXT: 8: this 131 // CHECK-NEXT: 9: [B1.8]->i 132 // CHECK-NEXT: 10: r([B1.9]) (Member initializer) 133 // WARNINGS-NEXT: 11: (CXXConstructExpr, class A) 134 // ANALYZER-NEXT: 11: (CXXConstructExpr, [B1.12], class A) 135 // CHECK-NEXT: 12: A a; 136 // CHECK-NEXT: Preds (2): B2 B3 137 // CHECK-NEXT: Succs (1): B0 138 // CHECK: [B2] 139 // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) 140 // ANALYZER-NEXT: 1: (CXXConstructExpr, A() (Base initializer), class A) 141 // CHECK-NEXT: 2: A([B2.1]) (Base initializer) 142 // CHECK-NEXT: Preds (1): B3 143 // CHECK-NEXT: Succs (1): B1 144 // CHECK: [B3] 145 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 146 // CHECK-NEXT: Preds (1): B4 147 // CHECK-NEXT: Succs (2): B1 B2 148 // CHECK: [B0 (EXIT)] 149 // CHECK-NEXT: Preds (1): B1 150 TestOrder::TestOrder() 151 : r(i), B(), i(), C() { 152 A a; 153 } 154 155 class TestControlFlow { 156 int x, y, z; 157 public: 158 TestControlFlow(bool b); 159 }; 160 161 // CHECK: TestControlFlow::TestControlFlow(bool b) 162 // CHECK: [B5 (ENTRY)] 163 // CHECK-NEXT: Succs (1): B4 164 // 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: this 168 // CHECK-NEXT: 4: [B1.3]->y 169 // 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 B3 173 // CHECK-NEXT: Succs (1): B0 174 // CHECK: [B2] 175 // CHECK-NEXT: 1: 0 176 // CHECK-NEXT: Preds (1): B4 177 // CHECK-NEXT: Succs (1): B1 178 // CHECK: [B3] 179 // CHECK-NEXT: 1: 1 180 // CHECK-NEXT: Preds (1): B4 181 // CHECK-NEXT: Succs (1): B1 182 // CHECK: [B4] 183 // CHECK-NEXT: 1: 0 184 // CHECK-NEXT: 2: x([B4.1]) (Member initializer) 185 // CHECK-NEXT: 3: b 186 // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool) 187 // CHECK-NEXT: T: [B4.4] ? ... : ... 188 // CHECK-NEXT: Preds (1): B5 189 // CHECK-NEXT: Succs (2): B2 B3 190 // CHECK: [B0 (EXIT)] 191 // CHECK-NEXT: Preds (1): B1 192 TestControlFlow::TestControlFlow(bool b) 193 : y(b ? 0 : 1) 194 , x(0) 195 , z(y) { 196 int v; 197 } 198 199 class TestDelegating { 200 int x, z; 201 public: 202 203 // CHECK: TestDelegating() 204 // CHECK: [B2 (ENTRY)] 205 // CHECK-NEXT: Succs (1): B1 206 // CHECK: [B1] 207 // CHECK-NEXT: 1: 2 208 // CHECK-NEXT: 2: 3 209 // 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): B2 213 // CHECK-NEXT: Succs (1): B0 214 // CHECK: [B0 (EXIT)] 215 // CHECK-NEXT: Preds (1): B1 216 TestDelegating() : TestDelegating(2, 3) {} 217 218 // CHECK: TestDelegating(int x, int z) 219 // CHECK: [B2 (ENTRY)] 220 // CHECK-NEXT: Succs (1): B1 221 // CHECK: [B1] 222 // CHECK-NEXT: 1: x 223 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 224 // CHECK-NEXT: 3: x([B1.2]) (Member initializer) 225 // CHECK-NEXT: 4: z 226 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, int) 227 // CHECK-NEXT: 6: z([B1.5]) (Member initializer) 228 // CHECK-NEXT: Preds (1): B2 229 // CHECK-NEXT: Succs (1): B0 230 // CHECK: [B0 (EXIT)] 231 // CHECK-NEXT: Preds (1): B1 232 TestDelegating(int x, int z) : x(x), z(z) {} 233 }; 234 235 class TestMoreControlFlow : public virtual A { 236 A a; 237 238 public: 239 TestMoreControlFlow(bool coin); 240 }; 241 242 // CHECK: TestMoreControlFlow::TestMoreControlFlow(bool coin) 243 // CHECK: [B10 (ENTRY)] 244 // CHECK-NEXT: Succs (1): B9 245 // CHECK: [B1] 246 // CHECK-NEXT: 1: [B4.2] ? [B2.1] : [B3.1] 247 // WARNINGS-NEXT: 2: [B1.1] (CXXConstructExpr, class A) 248 // ANALYZER-NEXT: 2: [B1.1] (CXXConstructExpr, a([B1.1]) (Member initializer), class A) 249 // CHECK-NEXT: 3: a([B1.2]) (Member initializer) 250 // CHECK-NEXT: Preds (2): B2 B3 251 // CHECK-NEXT: Succs (1): B0 252 // CHECK: [B2] 253 // CHECK-NEXT: 1: 3 254 // CHECK-NEXT: Preds (1): B4 255 // CHECK-NEXT: Succs (1): B1 256 // CHECK: [B3] 257 // CHECK-NEXT: 1: 4 258 // CHECK-NEXT: Preds (1): B4 259 // CHECK-NEXT: Succs (1): B1 260 // CHECK: [B4] 261 // CHECK-NEXT: 1: coin 262 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 263 // CHECK-NEXT: T: [B4.2] ? ... : ... 264 // CHECK-NEXT: Preds (2): B5 B9 265 // CHECK-NEXT: Succs (2): B2 B3 266 // CHECK: [B5] 267 // CHECK-NEXT: 1: [B8.2] ? [B6.1] : [B7.1] 268 // WARNINGS-NEXT: 2: [B5.1] (CXXConstructExpr, class A) 269 // ANALYZER-NEXT: 2: [B5.1] (CXXConstructExpr, A([B5.1]) (Base initializer), class A) 270 // CHECK-NEXT: 3: A([B5.2]) (Base initializer) 271 // CHECK-NEXT: Preds (2): B6 B7 272 // CHECK-NEXT: Succs (1): B4 273 // CHECK: [B6] 274 // CHECK-NEXT: 1: 1 275 // CHECK-NEXT: Preds (1): B8 276 // CHECK-NEXT: Succs (1): B5 277 // CHECK: [B7] 278 // CHECK-NEXT: 1: 2 279 // CHECK-NEXT: Preds (1): B8 280 // CHECK-NEXT: Succs (1): B5 281 // CHECK: [B8] 282 // CHECK-NEXT: 1: coin 283 // CHECK-NEXT: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool) 284 // CHECK-NEXT: T: [B8.2] ? ... : ... 285 // CHECK-NEXT: Preds (1): B9 286 // CHECK-NEXT: Succs (2): B6 B7 287 // CHECK: [B9] 288 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 289 // CHECK-NEXT: Preds (1): B10 290 // CHECK-NEXT: Succs (2): B4 B8 291 // CHECK: [B0 (EXIT)] 292 // CHECK-NEXT: Preds (1): B1 293 TestMoreControlFlow::TestMoreControlFlow(bool coin) 294 : A(coin ? 1 : 2), a(coin ? 3 : 4) {} 295