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: /*implicit*/(int)0 130 // CHECK-NEXT: 8: i([B1.7]) (Member initializer) 131 // CHECK-NEXT: 9: this 132 // CHECK-NEXT: 10: [B1.9]->i 133 // CHECK-NEXT: 11: r([B1.10]) (Member initializer) 134 // WARNINGS-NEXT: 12: (CXXConstructExpr, class A) 135 // ANALYZER-NEXT: 12: (CXXConstructExpr, [B1.13], class A) 136 // CHECK-NEXT: 13: A a; 137 // CHECK-NEXT: Preds (2): B2 B3 138 // CHECK-NEXT: Succs (1): B0 139 // CHECK: [B2] 140 // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) 141 // ANALYZER-NEXT: 1: (CXXConstructExpr, A() (Base initializer), class A) 142 // CHECK-NEXT: 2: A([B2.1]) (Base initializer) 143 // CHECK-NEXT: Preds (1): B3 144 // CHECK-NEXT: Succs (1): B1 145 // CHECK: [B3] 146 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 147 // CHECK-NEXT: Preds (1): B4 148 // CHECK-NEXT: Succs (2): B1 B2 149 // CHECK: [B0 (EXIT)] 150 // CHECK-NEXT: Preds (1): B1 151 TestOrder::TestOrder() 152 : r(i), B(), i(), C() { 153 A a; 154 } 155 156 class TestControlFlow { 157 int x, y, z; 158 public: 159 TestControlFlow(bool b); 160 }; 161 162 // CHECK: TestControlFlow::TestControlFlow(bool b) 163 // CHECK: [B5 (ENTRY)] 164 // CHECK-NEXT: Succs (1): B4 165 // CHECK: [B1] 166 // CHECK-NEXT: 1: [B4.4] ? [B2.1] : [B3.1] 167 // CHECK-NEXT: 2: y([B1.1]) (Member initializer) 168 // CHECK-NEXT: 3: this 169 // CHECK-NEXT: 4: [B1.3]->y 170 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, int) 171 // CHECK-NEXT: 6: z([B1.5]) (Member initializer) 172 // CHECK-NEXT: 7: int v; 173 // CHECK-NEXT: Preds (2): B2 B3 174 // CHECK-NEXT: Succs (1): B0 175 // CHECK: [B2] 176 // CHECK-NEXT: 1: 0 177 // CHECK-NEXT: Preds (1): B4 178 // CHECK-NEXT: Succs (1): B1 179 // CHECK: [B3] 180 // CHECK-NEXT: 1: 1 181 // CHECK-NEXT: Preds (1): B4 182 // CHECK-NEXT: Succs (1): B1 183 // CHECK: [B4] 184 // CHECK-NEXT: 1: 0 185 // CHECK-NEXT: 2: x([B4.1]) (Member initializer) 186 // CHECK-NEXT: 3: b 187 // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool) 188 // CHECK-NEXT: T: [B4.4] ? ... : ... 189 // CHECK-NEXT: Preds (1): B5 190 // CHECK-NEXT: Succs (2): B2 B3 191 // CHECK: [B0 (EXIT)] 192 // CHECK-NEXT: Preds (1): B1 193 TestControlFlow::TestControlFlow(bool b) 194 : y(b ? 0 : 1) 195 , x(0) 196 , z(y) { 197 int v; 198 } 199 200 class TestDelegating { 201 int x, z; 202 public: 203 204 // CHECK: TestDelegating() 205 // CHECK: [B2 (ENTRY)] 206 // CHECK-NEXT: Succs (1): B1 207 // CHECK: [B1] 208 // CHECK-NEXT: 1: 2 209 // CHECK-NEXT: 2: 3 210 // WARNINGS-NEXT: 3: [B1.1], [B1.2] (CXXConstructExpr, class TestDelegating) 211 // ANALYZER-NEXT: 3: [B1.1], [B1.2] (CXXConstructExpr, TestDelegating([B1.1], [B1.2]) (Delegating initializer), class TestDelegating) 212 // CHECK-NEXT: 4: TestDelegating([B1.3]) (Delegating initializer) 213 // CHECK-NEXT: Preds (1): B2 214 // CHECK-NEXT: Succs (1): B0 215 // CHECK: [B0 (EXIT)] 216 // CHECK-NEXT: Preds (1): B1 217 TestDelegating() : TestDelegating(2, 3) {} 218 219 // CHECK: TestDelegating(int x, int z) 220 // CHECK: [B2 (ENTRY)] 221 // CHECK-NEXT: Succs (1): B1 222 // CHECK: [B1] 223 // CHECK-NEXT: 1: x 224 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) 225 // CHECK-NEXT: 3: x([B1.2]) (Member initializer) 226 // CHECK-NEXT: 4: z 227 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, int) 228 // CHECK-NEXT: 6: z([B1.5]) (Member initializer) 229 // CHECK-NEXT: Preds (1): B2 230 // CHECK-NEXT: Succs (1): B0 231 // CHECK: [B0 (EXIT)] 232 // CHECK-NEXT: Preds (1): B1 233 TestDelegating(int x, int z) : x(x), z(z) {} 234 }; 235 236 class TestMoreControlFlow : public virtual A { 237 A a; 238 239 public: 240 TestMoreControlFlow(bool coin); 241 }; 242 243 // CHECK: TestMoreControlFlow::TestMoreControlFlow(bool coin) 244 // CHECK: [B10 (ENTRY)] 245 // CHECK-NEXT: Succs (1): B9 246 // CHECK: [B1] 247 // CHECK-NEXT: 1: [B4.2] ? [B2.1] : [B3.1] 248 // WARNINGS-NEXT: 2: [B1.1] (CXXConstructExpr, class A) 249 // ANALYZER-NEXT: 2: [B1.1] (CXXConstructExpr, a([B1.1]) (Member initializer), class A) 250 // CHECK-NEXT: 3: a([B1.2]) (Member initializer) 251 // CHECK-NEXT: Preds (2): B2 B3 252 // CHECK-NEXT: Succs (1): B0 253 // CHECK: [B2] 254 // CHECK-NEXT: 1: 3 255 // CHECK-NEXT: Preds (1): B4 256 // CHECK-NEXT: Succs (1): B1 257 // CHECK: [B3] 258 // CHECK-NEXT: 1: 4 259 // CHECK-NEXT: Preds (1): B4 260 // CHECK-NEXT: Succs (1): B1 261 // CHECK: [B4] 262 // CHECK-NEXT: 1: coin 263 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 264 // CHECK-NEXT: T: [B4.2] ? ... : ... 265 // CHECK-NEXT: Preds (2): B5 B9 266 // CHECK-NEXT: Succs (2): B2 B3 267 // CHECK: [B5] 268 // CHECK-NEXT: 1: [B8.2] ? [B6.1] : [B7.1] 269 // WARNINGS-NEXT: 2: [B5.1] (CXXConstructExpr, class A) 270 // ANALYZER-NEXT: 2: [B5.1] (CXXConstructExpr, A([B5.1]) (Base initializer), class A) 271 // CHECK-NEXT: 3: A([B5.2]) (Base initializer) 272 // CHECK-NEXT: Preds (2): B6 B7 273 // CHECK-NEXT: Succs (1): B4 274 // CHECK: [B6] 275 // CHECK-NEXT: 1: 1 276 // CHECK-NEXT: Preds (1): B8 277 // CHECK-NEXT: Succs (1): B5 278 // CHECK: [B7] 279 // CHECK-NEXT: 1: 2 280 // CHECK-NEXT: Preds (1): B8 281 // CHECK-NEXT: Succs (1): B5 282 // CHECK: [B8] 283 // CHECK-NEXT: 1: coin 284 // CHECK-NEXT: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool) 285 // CHECK-NEXT: T: [B8.2] ? ... : ... 286 // CHECK-NEXT: Preds (1): B9 287 // CHECK-NEXT: Succs (2): B6 B7 288 // CHECK: [B9] 289 // CHECK-NEXT: T: (See if most derived ctor has already initialized vbases) 290 // CHECK-NEXT: Preds (1): B10 291 // CHECK-NEXT: Succs (2): B4 B8 292 // CHECK: [B0 (EXIT)] 293 // CHECK-NEXT: Preds (1): B1 294 TestMoreControlFlow::TestMoreControlFlow(bool coin) 295 : A(coin ? 1 : 2), a(coin ? 3 : 4) {} 296