1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-lifetime=true,cfg-rich-constructors=false -analyzer-config cfg-implicit-dtors=false %s > %t 2>&1 2 // RUN: FileCheck --input-file=%t %s 3 4 extern bool UV; 5 class A { 6 public: 7 // CHECK: [B2 (ENTRY)] 8 // CHECK-NEXT: Succs (1): B1 9 // CHECK: [B1] 10 // CHECK-NEXT: 1: true 11 // CHECK-NEXT: 2: UV 12 // CHECK-NEXT: 3: [B1.2] = [B1.1] 13 // CHECK-NEXT: Preds (1): B2 14 // CHECK-NEXT: Succs (1): B0 15 // CHECK: [B0 (EXIT)] 16 // CHECK-NEXT: Preds (1): B1 17 A() { 18 UV = true; 19 } 20 // CHECK: [B3 (ENTRY)] 21 // CHECK-NEXT: Succs (1): B2 22 // CHECK: [B1] 23 // CHECK-NEXT: 1: 0 24 // CHECK-NEXT: 2: this 25 // CHECK-NEXT: 3: [B1.2]->p 26 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, LValueToRValue, int *) 27 // CHECK-NEXT: 5: *[B1.4] 28 // CHECK-NEXT: 6: [B1.5] = [B1.1] 29 // CHECK-NEXT: Preds (1): B2 30 // CHECK-NEXT: Succs (1): B0 31 // CHECK: [B2] 32 // CHECK-NEXT: 1: this 33 // CHECK-NEXT: 2: [B2.1]->p 34 // CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, LValueToRValue, int *) 35 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, PointerToBoolean, _Bool) 36 // CHECK-NEXT: T: if [B2.4] 37 // CHECK-NEXT: Preds (1): B3 38 // CHECK-NEXT: Succs (2): B1 B0 39 // CHECK: [B0 (EXIT)] 40 // CHECK-NEXT: Preds (2): B1 B2 41 ~A() { 42 if (p) 43 *p = 0; 44 } 45 // CHECK: [B2 (ENTRY)] 46 // CHECK-NEXT: Succs (1): B1 47 // CHECK: [B1] 48 // CHECK-NEXT: 1: 1 49 // CHECK-NEXT: 2: return [B1.1]; 50 // CHECK-NEXT: Preds (1): B2 51 // CHECK-NEXT: Succs (1): B0 52 // CHECK: [B0 (EXIT)] 53 // CHECK-NEXT: Preds (1): B1 54 operator int() const { return 1; } 55 int *p; 56 }; 57 58 // CHECK: [B2 (ENTRY)] 59 // CHECK-NEXT: Succs (1): B1 60 // CHECK: [B1] 61 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 62 // CHECK-NEXT: 2: A a; 63 // CHECK-NEXT: 3: a 64 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class A) 65 // CHECK-NEXT: 5: const A &b = a; 66 // CHECK-NEXT: 6: A() (CXXConstructExpr, class A) 67 // CHECK-NEXT: 7: [B1.6] (BindTemporary) 68 // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A) 69 // CHECK-NEXT: 9: [B1.8] 70 // CHECK-NEXT: 10: const A &c = A(); 71 // CHECK-NEXT: 11: [B1.10] (Lifetime ends) 72 // CHECK-NEXT: 12: [B1.2] (Lifetime ends) 73 // CHECK-NEXT: 13: [B1.5] (Lifetime ends) 74 // CHECK-NEXT: Preds (1): B2 75 // CHECK-NEXT: Succs (1): B0 76 // CHECK: [B0 (EXIT)] 77 // CHECK-NEXT: Preds (1): B1 78 void test_const_ref() { 79 A a; 80 const A &b = a; 81 const A &c = A(); 82 } 83 84 // CHECK: [B2 (ENTRY)] 85 // CHECK-NEXT: Succs (1): B1 86 // CHECK: [B1] 87 // CHECK-NEXT: 1: (CXXConstructExpr, class A [2]) 88 // CHECK-NEXT: 2: A a[2]; 89 // CHECK-NEXT: 3: (CXXConstructExpr, class A [0]) 90 // CHECK-NEXT: 4: A b[0]; 91 // lifetime of a ends when its destructors are run 92 // CHECK-NEXT: 5: [B1.2] (Lifetime ends) 93 // lifetime of b ends when its storage duration ends 94 // CHECK-NEXT: 6: [B1.4] (Lifetime ends) 95 // CHECK-NEXT: Preds (1): B2 96 // CHECK-NEXT: Succs (1): B0 97 // CHECK: [B0 (EXIT)] 98 // CHECK-NEXT: Preds (1): B1 99 void test_array() { 100 A a[2]; 101 A b[0]; 102 } 103 104 // CHECK: [B2 (ENTRY)] 105 // CHECK-NEXT: Succs (1): B1 106 // CHECK: [B1] 107 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 108 // CHECK-NEXT: 2: A a; 109 // CHECK-NEXT: 3: (CXXConstructExpr, class A) 110 // CHECK-NEXT: 4: A c; 111 // CHECK-NEXT: 5: (CXXConstructExpr, class A) 112 // CHECK-NEXT: 6: A d; 113 // CHECK-NEXT: 7: [B1.6] (Lifetime ends) 114 // CHECK-NEXT: 8: [B1.4] (Lifetime ends) 115 // CHECK-NEXT: 9: (CXXConstructExpr, class A) 116 // CHECK-NEXT: 10: A b; 117 // CHECK-NEXT: 11: [B1.10] (Lifetime ends) 118 // CHECK-NEXT: 12: [B1.2] (Lifetime ends) 119 // CHECK-NEXT: Preds (1): B2 120 // CHECK-NEXT: Succs (1): B0 121 // CHECK: [B0 (EXIT)] 122 // CHECK-NEXT: Preds (1): B1 123 void test_scope() { 124 A a; 125 { 126 A c; 127 A d; 128 } 129 A b; 130 } 131 132 // CHECK: [B4 (ENTRY)] 133 // CHECK-NEXT: Succs (1): B3 134 // CHECK: [B1] 135 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 136 // CHECK-NEXT: 2: A c; 137 // CHECK-NEXT: 3: [B1.2] (Lifetime ends) 138 // CHECK-NEXT: 4: [B3.4] (Lifetime ends) 139 // CHECK-NEXT: 5: [B3.2] (Lifetime ends) 140 // CHECK-NEXT: Preds (1): B3 141 // CHECK-NEXT: Succs (1): B0 142 // CHECK: [B2] 143 // CHECK-NEXT: 1: return; 144 // CHECK-NEXT: 2: [B3.4] (Lifetime ends) 145 // CHECK-NEXT: 3: [B3.2] (Lifetime ends) 146 // CHECK-NEXT: Preds (1): B3 147 // CHECK-NEXT: Succs (1): B0 148 // CHECK: [B3] 149 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 150 // CHECK-NEXT: 2: A a; 151 // CHECK-NEXT: 3: (CXXConstructExpr, class A) 152 // CHECK-NEXT: 4: A b; 153 // CHECK-NEXT: 5: UV 154 // CHECK-NEXT: 6: [B3.5] (ImplicitCastExpr, LValueToRValue, _Bool) 155 // CHECK-NEXT: T: if [B3.6] 156 // CHECK-NEXT: Preds (1): B4 157 // CHECK-NEXT: Succs (2): B2 B1 158 159 // CHECK: [B0 (EXIT)] 160 // CHECK-NEXT: Preds (2): B1 B2 161 void test_return() { 162 A a; 163 A b; 164 if (UV) 165 return; 166 A c; 167 } 168 169 // CHECK: [B5 (ENTRY)] 170 // CHECK-NEXT: Succs (1): B4 171 // CHECK: [B1] 172 // CHECK-NEXT: 1: [B4.6] (Lifetime ends) 173 // CHECK-NEXT: 2: [B4.2] (Lifetime ends) 174 // CHECK-NEXT: Preds (2): B2 B3 175 // CHECK-NEXT: Succs (1): B0 176 // CHECK: [B2] 177 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 178 // CHECK-NEXT: 2: A c; 179 // CHECK-NEXT: 3: [B2.2] (Lifetime ends) 180 // CHECK-NEXT: Preds (1): B4 181 // CHECK-NEXT: Succs (1): B1 182 // CHECK: [B3] 183 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 184 // CHECK-NEXT: 2: A c; 185 // CHECK-NEXT: 3: [B3.2] (Lifetime ends) 186 // CHECK-NEXT: Preds (1): B4 187 // CHECK-NEXT: Succs (1): B1 188 // CHECK: [B4] 189 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 190 // CHECK-NEXT: 2: A a; 191 // CHECK-NEXT: 3: a 192 // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, NoOp, const class A) 193 // CHECK-NEXT: 5: [B4.4] (CXXConstructExpr, class A) 194 // CHECK-NEXT: 6: A b = a; 195 // CHECK-NEXT: 7: b 196 // CHECK-NEXT: 8: [B4.7] (ImplicitCastExpr, NoOp, const class A) 197 // CHECK-NEXT: 9: [B4.8].operator int 198 // CHECK-NEXT: 10: [B4.8] 199 // CHECK-NEXT: 11: [B4.10] (ImplicitCastExpr, UserDefinedConversion, int) 200 // CHECK-NEXT: 12: [B4.11] (ImplicitCastExpr, IntegralToBoolean, _Bool) 201 // CHECK-NEXT: T: if [B4.12] 202 // CHECK-NEXT: Preds (1): B5 203 // CHECK-NEXT: Succs (2): B3 B2 204 // CHECK: [B0 (EXIT)] 205 // CHECK-NEXT: Preds (1): B1 206 void test_if_implicit_scope() { 207 A a; 208 if (A b = a) 209 A c; 210 else 211 A c; 212 } 213 214 // CHECK: [B9 (ENTRY)] 215 // CHECK-NEXT: Succs (1): B8 216 // CHECK: [B1] 217 // CHECK-NEXT: 1: [B8.6] (Lifetime ends) 218 // CHECK-NEXT: 2: (CXXConstructExpr, class A) 219 // CHECK-NEXT: 3: A e; 220 // CHECK-NEXT: 4: [B1.3] (Lifetime ends) 221 // CHECK-NEXT: 5: [B8.2] (Lifetime ends) 222 // CHECK-NEXT: Preds (2): B2 B5 223 // CHECK-NEXT: Succs (1): B0 224 // CHECK: [B2] 225 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 226 // CHECK-NEXT: 2: A d; 227 // CHECK-NEXT: 3: [B2.2] (Lifetime ends) 228 // CHECK-NEXT: 4: [B4.2] (Lifetime ends) 229 // CHECK-NEXT: Preds (1): B4 230 // CHECK-NEXT: Succs (1): B1 231 // CHECK: [B3] 232 // CHECK-NEXT: 1: return; 233 // CHECK-NEXT: 2: [B4.2] (Lifetime ends) 234 // CHECK-NEXT: 3: [B8.6] (Lifetime ends) 235 // CHECK-NEXT: 4: [B8.2] (Lifetime ends) 236 // CHECK-NEXT: Preds (1): B4 237 // CHECK-NEXT: Succs (1): B0 238 // CHECK: [B4] 239 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 240 // CHECK-NEXT: 2: A c; 241 // CHECK-NEXT: 3: UV 242 // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool) 243 // CHECK-NEXT: T: if [B4.4] 244 // CHECK-NEXT: Preds (1): B8 245 // CHECK-NEXT: Succs (2): B3 B2 246 // CHECK: [B5] 247 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 248 // CHECK-NEXT: 2: A d; 249 // CHECK-NEXT: 3: [B5.2] (Lifetime ends) 250 // CHECK-NEXT: 4: [B7.2] (Lifetime ends) 251 // CHECK-NEXT: Preds (1): B7 252 // CHECK-NEXT: Succs (1): B1 253 // CHECK: [B6] 254 // CHECK-NEXT: 1: return; 255 // CHECK-NEXT: 2: [B7.2] (Lifetime ends) 256 // CHECK-NEXT: 3: [B8.6] (Lifetime ends) 257 // CHECK-NEXT: 4: [B8.2] (Lifetime ends) 258 // CHECK-NEXT: Preds (1): B7 259 // CHECK-NEXT: Succs (1): B0 260 // CHECK: [B7] 261 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 262 // CHECK-NEXT: 2: A c; 263 // CHECK-NEXT: 3: UV 264 // CHECK-NEXT: 4: [B7.3] (ImplicitCastExpr, LValueToRValue, _Bool) 265 // CHECK-NEXT: T: if [B7.4] 266 // CHECK-NEXT: Preds (1): B8 267 // CHECK-NEXT: Succs (2): B6 B5 268 // CHECK: [B8] 269 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 270 // CHECK-NEXT: 2: A a; 271 // CHECK-NEXT: 3: a 272 // CHECK-NEXT: 4: [B8.3] (ImplicitCastExpr, NoOp, const class A) 273 // CHECK-NEXT: 5: [B8.4] (CXXConstructExpr, class A) 274 // CHECK-NEXT: 6: A b = a; 275 // CHECK-NEXT: 7: b 276 // CHECK-NEXT: 8: [B8.7] (ImplicitCastExpr, NoOp, const class A) 277 // CHECK-NEXT: 9: [B8.8].operator int 278 // CHECK-NEXT: 10: [B8.8] 279 // CHECK-NEXT: 11: [B8.10] (ImplicitCastExpr, UserDefinedConversion, int) 280 // CHECK-NEXT: 12: [B8.11] (ImplicitCastExpr, IntegralToBoolean, _Bool) 281 // CHECK-NEXT: T: if [B8.12] 282 // CHECK-NEXT: Preds (1): B9 283 // CHECK-NEXT: Succs (2): B7 B4 284 // CHECK: [B0 (EXIT)] 285 // CHECK-NEXT: Preds (3): B1 B3 B6 286 void test_if_jumps() { 287 A a; 288 if (A b = a) { 289 A c; 290 if (UV) 291 return; 292 A d; 293 } else { 294 A c; 295 if (UV) 296 return; 297 A d; 298 } 299 A e; 300 } 301 302 // CHECK: [B6 (ENTRY)] 303 // CHECK-NEXT: Succs (1): B5 304 // CHECK: [B1] 305 // CHECK-NEXT: 1: [B4.4] (Lifetime ends) 306 // CHECK-NEXT: 2: [B5.2] (Lifetime ends) 307 // CHECK-NEXT: Preds (1): B4 308 // CHECK-NEXT: Succs (1): B0 309 // CHECK: [B2] 310 // CHECK-NEXT: Preds (1): B3 311 // CHECK-NEXT: Succs (1): B4 312 // CHECK: [B3] 313 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 314 // CHECK-NEXT: 2: A c; 315 // CHECK-NEXT: 3: [B3.2] (Lifetime ends) 316 // CHECK-NEXT: 4: [B4.4] (Lifetime ends) 317 // CHECK-NEXT: Preds (1): B4 318 // CHECK-NEXT: Succs (1): B2 319 // CHECK: [B4] 320 // CHECK-NEXT: 1: a 321 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) 322 // CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A) 323 // CHECK-NEXT: 4: A b = a; 324 // CHECK-NEXT: 5: b 325 // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) 326 // CHECK-NEXT: 7: [B4.6].operator int 327 // CHECK-NEXT: 8: [B4.6] 328 // CHECK-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) 329 // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) 330 // CHECK-NEXT: T: while [B4.10] 331 // CHECK-NEXT: Preds (2): B2 B5 332 // CHECK-NEXT: Succs (2): B3 B1 333 // CHECK: [B5] 334 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 335 // CHECK-NEXT: 2: A a; 336 // CHECK-NEXT: Preds (1): B6 337 // CHECK-NEXT: Succs (1): B4 338 // CHECK: [B0 (EXIT)] 339 // CHECK-NEXT: Preds (1): B1 340 void test_while_implicit_scope() { 341 A a; 342 while (A b = a) 343 A c; 344 } 345 346 // CHECK: [B12 (ENTRY)] 347 // CHECK-NEXT: Succs (1): B11 348 // CHECK: [B1] 349 // CHECK-NEXT: 1: [B10.4] (Lifetime ends) 350 // CHECK-NEXT: 2: (CXXConstructExpr, class A) 351 // CHECK-NEXT: 3: A e; 352 // CHECK-NEXT: 4: [B1.3] (Lifetime ends) 353 // CHECK-NEXT: 5: [B11.2] (Lifetime ends) 354 // CHECK-NEXT: Preds (2): B8 B10 355 // CHECK-NEXT: Succs (1): B0 356 // CHECK: [B2] 357 // CHECK-NEXT: Preds (2): B3 B6 358 // CHECK-NEXT: Succs (1): B10 359 // CHECK: [B3] 360 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 361 // CHECK-NEXT: 2: A d; 362 // CHECK-NEXT: 3: [B3.2] (Lifetime ends) 363 // CHECK-NEXT: 4: [B9.2] (Lifetime ends) 364 // CHECK-NEXT: 5: [B10.4] (Lifetime ends) 365 // CHECK-NEXT: Preds (1): B5 366 // CHECK-NEXT: Succs (1): B2 367 // CHECK: [B4] 368 // CHECK-NEXT: 1: return; 369 // CHECK-NEXT: 2: [B9.2] (Lifetime ends) 370 // CHECK-NEXT: 3: [B10.4] (Lifetime ends) 371 // CHECK-NEXT: 4: [B11.2] (Lifetime ends) 372 // CHECK-NEXT: Preds (1): B5 373 // CHECK-NEXT: Succs (1): B0 374 // CHECK: [B5] 375 // CHECK-NEXT: 1: UV 376 // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) 377 // CHECK-NEXT: T: if [B5.2] 378 // CHECK-NEXT: Preds (1): B7 379 // CHECK-NEXT: Succs (2): B4 B3 380 // CHECK: [B6] 381 // CHECK-NEXT: 1: [B9.2] (Lifetime ends) 382 // CHECK-NEXT: 2: [B10.4] (Lifetime ends) 383 // CHECK-NEXT: T: continue; 384 // CHECK-NEXT: Preds (1): B7 385 // CHECK-NEXT: Succs (1): B2 386 // CHECK: [B7] 387 // CHECK-NEXT: 1: UV 388 // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) 389 // CHECK-NEXT: T: if [B7.2] 390 // CHECK-NEXT: Preds (1): B9 391 // CHECK-NEXT: Succs (2): B6 B5 392 // CHECK: [B8] 393 // CHECK-NEXT: 1: [B9.2] (Lifetime ends) 394 // CHECK-NEXT: T: break; 395 // CHECK-NEXT: Preds (1): B9 396 // CHECK-NEXT: Succs (1): B1 397 // CHECK: [B9] 398 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 399 // CHECK-NEXT: 2: A c; 400 // CHECK-NEXT: 3: UV 401 // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) 402 // CHECK-NEXT: T: if [B9.4] 403 // CHECK-NEXT: Preds (1): B10 404 // CHECK-NEXT: Succs (2): B8 B7 405 // CHECK: [B10] 406 // CHECK-NEXT: 1: a 407 // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) 408 // CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A) 409 // CHECK-NEXT: 4: A b = a; 410 // CHECK-NEXT: 5: b 411 // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) 412 // CHECK-NEXT: 7: [B10.6].operator int 413 // CHECK-NEXT: 8: [B10.6] 414 // CHECK-NEXT: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) 415 // CHECK-NEXT: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) 416 // CHECK-NEXT: T: while [B10.10] 417 // CHECK-NEXT: Preds (2): B2 B11 418 // CHECK-NEXT: Succs (2): B9 B1 419 // CHECK: [B11] 420 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 421 // CHECK-NEXT: 2: A a; 422 // CHECK-NEXT: Preds (1): B12 423 // CHECK-NEXT: Succs (1): B10 424 // CHECK: [B0 (EXIT)] 425 // CHECK-NEXT: Preds (2): B1 B4 426 void test_while_jumps() { 427 A a; 428 while (A b = a) { 429 A c; 430 if (UV) 431 break; 432 if (UV) 433 continue; 434 if (UV) 435 return; 436 A d; 437 } 438 A e; 439 } 440 441 // CHECK: [B12 (ENTRY)] 442 // CHECK-NEXT: Succs (1): B11 443 // CHECK: [B1] 444 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 445 // CHECK-NEXT: 2: A d; 446 // CHECK-NEXT: 3: [B1.2] (Lifetime ends) 447 // CHECK-NEXT: 4: [B11.2] (Lifetime ends) 448 // CHECK-NEXT: Preds (2): B8 B2 449 // CHECK-NEXT: Succs (1): B0 450 // CHECK: [B2] 451 // CHECK-NEXT: 1: UV 452 // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, _Bool) 453 // CHECK-NEXT: T: do ... while [B2.2] 454 // CHECK-NEXT: Preds (2): B3 B6 455 // CHECK-NEXT: Succs (2): B10 B1 456 // CHECK: [B3] 457 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 458 // CHECK-NEXT: 2: A c; 459 // CHECK-NEXT: 3: [B3.2] (Lifetime ends) 460 // CHECK-NEXT: 4: [B9.2] (Lifetime ends) 461 // CHECK-NEXT: Preds (1): B5 462 // CHECK-NEXT: Succs (1): B2 463 // CHECK: [B4] 464 // CHECK-NEXT: 1: return; 465 // CHECK-NEXT: 2: [B9.2] (Lifetime ends) 466 // CHECK-NEXT: 3: [B11.2] (Lifetime ends) 467 // CHECK-NEXT: Preds (1): B5 468 // CHECK-NEXT: Succs (1): B0 469 // CHECK: [B5] 470 // CHECK-NEXT: 1: UV 471 // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) 472 // CHECK-NEXT: T: if [B5.2] 473 // CHECK-NEXT: Preds (1): B7 474 // CHECK-NEXT: Succs (2): B4 B3 475 // CHECK: [B6] 476 // CHECK-NEXT: 1: [B9.2] (Lifetime ends) 477 // CHECK-NEXT: T: continue; 478 // CHECK-NEXT: Preds (1): B7 479 // CHECK-NEXT: Succs (1): B2 480 // CHECK: [B7] 481 // CHECK-NEXT: 1: UV 482 // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) 483 // CHECK-NEXT: T: if [B7.2] 484 // CHECK-NEXT: Preds (1): B9 485 // CHECK-NEXT: Succs (2): B6 B5 486 // CHECK: [B8] 487 // CHECK-NEXT: 1: [B9.2] (Lifetime ends) 488 // CHECK-NEXT: T: break; 489 // CHECK-NEXT: Preds (1): B9 490 // CHECK-NEXT: Succs (1): B1 491 // CHECK: [B9] 492 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 493 // CHECK-NEXT: 2: A b; 494 // CHECK-NEXT: 3: UV 495 // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) 496 // CHECK-NEXT: T: if [B9.4] 497 // CHECK-NEXT: Preds (2): B10 B11 498 // CHECK-NEXT: Succs (2): B8 B7 499 // CHECK: [B10] 500 // CHECK-NEXT: Preds (1): B2 501 // CHECK-NEXT: Succs (1): B9 502 // CHECK: [B11] 503 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 504 // CHECK-NEXT: 2: A a; 505 // CHECK-NEXT: Preds (1): B12 506 // CHECK-NEXT: Succs (1): B9 507 // CHECK: [B0 (EXIT)] 508 // CHECK-NEXT: Preds (2): B1 B4 509 void test_do_jumps() { 510 A a; 511 do { 512 A b; 513 if (UV) 514 break; 515 if (UV) 516 continue; 517 if (UV) 518 return; 519 A c; 520 } while (UV); 521 A d; 522 } 523 524 // CHECK: [B6 (ENTRY)] 525 // CHECK-NEXT: Succs (1): B5 526 // CHECK: [B1] 527 // CHECK-NEXT: 1: [B4.4] (Lifetime ends) 528 // CHECK-NEXT: 2: [B5.2] (Lifetime ends) 529 // CHECK-NEXT: Preds (1): B4 530 // CHECK-NEXT: Succs (1): B0 531 // CHECK: [B2] 532 // CHECK-NEXT: Preds (1): B3 533 // CHECK-NEXT: Succs (1): B4 534 // CHECK: [B3] 535 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 536 // CHECK-NEXT: 2: A c; 537 // CHECK-NEXT: 3: [B3.2] (Lifetime ends) 538 // CHECK-NEXT: 4: [B4.4] (Lifetime ends) 539 // CHECK-NEXT: Preds (1): B4 540 // CHECK-NEXT: Succs (1): B2 541 // CHECK: [B4] 542 // CHECK-NEXT: 1: a 543 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) 544 // CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A) 545 // CHECK-NEXT: 4: A b = a; 546 // CHECK-NEXT: 5: b 547 // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) 548 // CHECK-NEXT: 7: [B4.6].operator int 549 // CHECK-NEXT: 8: [B4.6] 550 // CHECK-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) 551 // CHECK-NEXT: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) 552 // CHECK-NEXT: T: for (...; [B4.10]; ) 553 // CHECK-NEXT: Preds (2): B2 B5 554 // CHECK-NEXT: Succs (2): B3 B1 555 // CHECK: [B5] 556 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 557 // CHECK-NEXT: 2: A a; 558 // CHECK-NEXT: Preds (1): B6 559 // CHECK-NEXT: Succs (1): B4 560 // CHECK: [B0 (EXIT)] 561 // CHECK-NEXT: Preds (1): B1 562 void test_for_implicit_scope() { 563 for (A a; A b = a;) 564 A c; 565 } 566 567 // CHECK: [B12 (ENTRY)] 568 // CHECK-NEXT: Succs (1): B11 569 // CHECK: [B1] 570 // CHECK-NEXT: 1: [B10.4] (Lifetime ends) 571 // CHECK-NEXT: 2: [B11.4] (Lifetime ends) 572 // CHECK-NEXT: 3: (CXXConstructExpr, class A) 573 // CHECK-NEXT: 4: A f; 574 // CHECK-NEXT: 5: [B1.4] (Lifetime ends) 575 // CHECK-NEXT: 6: [B11.2] (Lifetime ends) 576 // CHECK-NEXT: Preds (2): B8 B10 577 // CHECK-NEXT: Succs (1): B0 578 // CHECK: [B2] 579 // CHECK-NEXT: Preds (2): B3 B6 580 // CHECK-NEXT: Succs (1): B10 581 // CHECK: [B3] 582 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 583 // CHECK-NEXT: 2: A e; 584 // CHECK-NEXT: 3: [B3.2] (Lifetime ends) 585 // CHECK-NEXT: 4: [B9.2] (Lifetime ends) 586 // CHECK-NEXT: 5: [B10.4] (Lifetime ends) 587 // CHECK-NEXT: Preds (1): B5 588 // CHECK-NEXT: Succs (1): B2 589 // CHECK: [B4] 590 // CHECK-NEXT: 1: return; 591 // CHECK-NEXT: 2: [B9.2] (Lifetime ends) 592 // CHECK-NEXT: 3: [B10.4] (Lifetime ends) 593 // CHECK-NEXT: 4: [B11.4] (Lifetime ends) 594 // CHECK-NEXT: 5: [B11.2] (Lifetime ends) 595 // CHECK-NEXT: Preds (1): B5 596 // CHECK-NEXT: Succs (1): B0 597 // CHECK: [B5] 598 // CHECK-NEXT: 1: UV 599 // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) 600 // CHECK-NEXT: T: if [B5.2] 601 // CHECK-NEXT: Preds (1): B7 602 // CHECK-NEXT: Succs (2): B4 B3 603 // CHECK: [B6] 604 // CHECK-NEXT: 1: [B9.2] (Lifetime ends) 605 // CHECK-NEXT: T: continue; 606 // CHECK-NEXT: Preds (1): B7 607 // CHECK-NEXT: Succs (1): B2 608 // CHECK: [B7] 609 // CHECK-NEXT: 1: UV 610 // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) 611 // CHECK-NEXT: T: if [B7.2] 612 // CHECK-NEXT: Preds (1): B9 613 // CHECK-NEXT: Succs (2): B6 B5 614 // CHECK: [B8] 615 // CHECK-NEXT: 1: [B9.2] (Lifetime ends) 616 // CHECK-NEXT: T: break; 617 // CHECK-NEXT: Preds (1): B9 618 // CHECK-NEXT: Succs (1): B1 619 // CHECK: [B9] 620 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 621 // CHECK-NEXT: 2: A d; 622 // CHECK-NEXT: 3: UV 623 // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) 624 // CHECK-NEXT: T: if [B9.4] 625 // CHECK-NEXT: Preds (1): B10 626 // CHECK-NEXT: Succs (2): B8 B7 627 // CHECK: [B10] 628 // CHECK-NEXT: 1: b 629 // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) 630 // CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A) 631 // CHECK-NEXT: 4: A c = b; 632 // CHECK-NEXT: 5: c 633 // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) 634 // CHECK-NEXT: 7: [B10.6].operator int 635 // CHECK-NEXT: 8: [B10.6] 636 // CHECK-NEXT: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) 637 // CHECK-NEXT: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) 638 // CHECK-NEXT: T: for (...; [B10.10]; ) 639 // CHECK-NEXT: Preds (2): B2 B11 640 // CHECK-NEXT: Succs (2): B9 B1 641 // CHECK: [B11] 642 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 643 // CHECK-NEXT: 2: A a; 644 // CHECK-NEXT: 3: (CXXConstructExpr, class A) 645 // CHECK-NEXT: 4: A b; 646 // CHECK-NEXT: Preds (1): B12 647 // CHECK-NEXT: Succs (1): B10 648 // CHECK: [B0 (EXIT)] 649 // CHECK-NEXT: Preds (2): B1 B4 650 void test_for_jumps() { 651 A a; 652 for (A b; A c = b;) { 653 A d; 654 if (UV) 655 break; 656 if (UV) 657 continue; 658 if (UV) 659 return; 660 A e; 661 } 662 A f; 663 } 664 665 // CHECK: [B2 (ENTRY)] 666 // CHECK-NEXT: Succs (1): B1 667 // CHECK: [B1] 668 // CHECK-NEXT: 1: (CXXConstructExpr, class A) 669 // CHECK-NEXT: 2: A a; 670 // CHECK-NEXT: 3: int n; 671 // CHECK-NEXT: 4: n 672 // CHECK-NEXT: 5: &[B1.4] 673 // CHECK-NEXT: 6: a 674 // CHECK-NEXT: 7: [B1.6].p 675 // CHECK-NEXT: 8: [B1.7] = [B1.5] 676 // CHECK-NEXT: 9: [B1.2] (Lifetime ends) 677 // CHECK-NEXT: 10: [B1.3] (Lifetime ends) 678 // CHECK-NEXT: Preds (1): B2 679 // CHECK-NEXT: Succs (1): B0 680 // CHECK: [B0 (EXIT)] 681 // CHECK-NEXT: Preds (1): B1 682 void test_trivial_vs_non_trivial_order() { 683 A a; 684 int n; 685 a.p = &n; 686 } 687 688 // CHECK: [B4 (ENTRY)] 689 // CHECK-NEXT: Succs (1): B3 690 // CHECK: [B1] 691 // CHECK-NEXT: a: 692 // CHECK-NEXT: 1: 1 693 // CHECK-NEXT: 2: i 694 // CHECK-NEXT: 3: [B1.2] = [B1.1] 695 // CHECK-NEXT: 4: [B2.1] (Lifetime ends) 696 // CHECK-NEXT: Preds (2): B2 B3 697 // CHECK-NEXT: Succs (1): B0 698 // CHECK: [B2] 699 // CHECK-NEXT: 1: int i; 700 // CHECK-NEXT: Succs (1): B1 701 // CHECK: [B3] 702 // CHECK-NEXT: T: goto a; 703 // CHECK-NEXT: Preds (1): B4 704 // CHECK-NEXT: Succs (1): B1 705 // CHECK: [B0 (EXIT)] 706 // CHECK-NEXT: Preds (1): B1 707 void goto_past_declaration() { 708 goto a; 709 int i; 710 a: 711 i = 1; 712 } 713 714 // CHECK: [B4 (ENTRY)] 715 // CHECK-NEXT: Succs (1): B3 716 // CHECK: [B1] 717 // CHECK-NEXT: a: 718 // CHECK-NEXT: 1: 1 719 // CHECK-NEXT: 2: k 720 // CHECK-NEXT: 3: [B1.2] = [B1.1] 721 // CHECK-NEXT: 4: [B2.4] (Lifetime ends) 722 // CHECK-NEXT: Preds (2): B2 B3 723 // CHECK-NEXT: Succs (1): B0 724 // CHECK: [B2] 725 // CHECK-NEXT: 1: int j; 726 // CHECK-NEXT: 2: [B2.1] (Lifetime ends) 727 // CHECK-NEXT: 3: [B3.1] (Lifetime ends) 728 // CHECK-NEXT: 4: int k; 729 // CHECK-NEXT: Succs (1): B1 730 // CHECK: [B3] 731 // CHECK-NEXT: 1: int i; 732 // CHECK-NEXT: 2: [B3.1] (Lifetime ends) 733 // CHECK-NEXT: T: goto a; 734 // CHECK-NEXT: Preds (1): B4 735 // CHECK-NEXT: Succs (1): B1 736 // CHECK: [B0 (EXIT)] 737 // CHECK-NEXT: Preds (1): B1 738 void goto_past_declaration2() { 739 { 740 int i; 741 goto a; 742 int j; 743 } 744 { 745 int k; 746 a: 747 k = 1; 748 } 749 } 750 751 struct B { 752 ~B(); 753 }; 754 755 // CHECK: [B4 (ENTRY)] 756 // CHECK-NEXT: Succs (1): B3 757 // CHECK: [B1] 758 // CHECK-NEXT: 1: i 759 // CHECK-NEXT: 2: [B1.1]++ 760 // CHECK-NEXT: 3: [B2.2] (Lifetime ends) 761 // CHECK-NEXT: 4: [B3.1] (Lifetime ends) 762 // CHECK-NEXT: Succs (1): B0 763 // CHECK: [B2] 764 // CHECK-NEXT: label: 765 // CHECK-NEXT: 1: (CXXConstructExpr, struct B) 766 // CHECK-NEXT: 2: B b; 767 // CHECK-NEXT: 3: [B2.2] (Lifetime ends) 768 // CHECK-NEXT: T: goto label; 769 // CHECK-NEXT: Preds (2): B3 B2 770 // CHECK-NEXT: Succs (1): B2 771 // CHECK: [B3] 772 // CHECK-NEXT: 1: int i; 773 // CHECK-NEXT: Preds (1): B4 774 // CHECK-NEXT: Succs (1): B2 775 // CHECK: [B0 (EXIT)] 776 // CHECK-NEXT: Preds (1): B1 777 int backpatched_goto() { 778 int i; 779 label: 780 B b; 781 goto label; 782 i++; 783 } 784