diff --git a/clang/test/Analysis/lifetime-cfg-output.cpp b/clang/test/Analysis/lifetime-cfg-output.cpp index f9015e0c00cec..d8b8dc4a71d4a 100644 --- a/clang/test/Analysis/lifetime-cfg-output.cpp +++ b/clang/test/Analysis/lifetime-cfg-output.cpp @@ -1,6 +1,13 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-lifetime=true,cfg-temporary-dtors=false,cfg-rich-constructors=false -analyzer-config cfg-implicit-dtors=false %s > %t 2>&1 +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-lifetime=true %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s +// FIXME Most of the cases in this file test only with the objects of type `A`, +// that has a non-trivial destructor. The types with a trivial destructor +// ends their lifetime when the underlying memory is released, i.e. they +// are destroyed last, after all objects with non-trivial destructors. +// Consequently, they are handled differently in code, and we should make +// sure that test cover also trivially destructible types. + extern bool UV; class A { public: @@ -58,19 +65,21 @@ class A { // CHECK: [B2 (ENTRY)] // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: 3: a // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const A) // CHECK-NEXT: 5: const A &b = a; -// CHECK-NEXT: 6: A() (CXXConstructExpr, A) +// CHECK-NEXT: 6: A() (CXXConstructExpr, [B1.9], A) // CHECK-NEXT: 7: [B1.6] (BindTemporary) // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const A) // CHECK-NEXT: 9: [B1.8] // CHECK-NEXT: 10: const A &c = A(); -// CHECK-NEXT: 11: [B1.10] (Lifetime ends) -// CHECK-NEXT: 12: [B1.2] (Lifetime ends) -// CHECK-NEXT: 13: [B1.5] (Lifetime ends) +// CHECK-NEXT: 11: [B1.10].~A() (Implicit destructor) +// CHECK-NEXT: 12: [B1.10] (Lifetime ends) +// CHECK-NEXT: 13: [B1.2].~A() (Implicit destructor) +// CHECK-NEXT: 14: [B1.2] (Lifetime ends) +// CHECK-NEXT: 15: [B1.5] (Lifetime ends) // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B0 // CHECK: [B0 (EXIT)] @@ -84,14 +93,15 @@ void test_const_ref() { // CHECK: [B2 (ENTRY)] // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] -// CHECK-NEXT: 1: (CXXConstructExpr, A[2]) +// CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], A[2]) // CHECK-NEXT: 2: A a[2]; -// CHECK-NEXT: 3: (CXXConstructExpr, A[0]) +// CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], A[0]) // CHECK-NEXT: 4: A b[0]; +// CHECK-NEXT: 5: [B1.2].~A[2]() (Implicit destructor) // lifetime of a ends when its destructors are run -// CHECK-NEXT: 5: [B1.2] (Lifetime ends) +// CHECK-NEXT: 6: [B1.2] (Lifetime ends) // lifetime of b ends when its storage duration ends -// CHECK-NEXT: 6: [B1.4] (Lifetime ends) +// CHECK-NEXT: 7: [B1.4] (Lifetime ends) // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B0 // CHECK: [B0 (EXIT)] @@ -104,18 +114,22 @@ void test_array() { // CHECK: [B2 (ENTRY)] // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], A) // CHECK-NEXT: 2: A a; -// CHECK-NEXT: 3: (CXXConstructExpr, A) +// CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], A) // CHECK-NEXT: 4: A c; -// CHECK-NEXT: 5: (CXXConstructExpr, A) +// CHECK-NEXT: 5: (CXXConstructExpr, [B1.6], A) // CHECK-NEXT: 6: A d; -// CHECK-NEXT: 7: [B1.6] (Lifetime ends) -// CHECK-NEXT: 8: [B1.4] (Lifetime ends) -// CHECK-NEXT: 9: (CXXConstructExpr, A) -// CHECK-NEXT: 10: A b; -// CHECK-NEXT: 11: [B1.10] (Lifetime ends) -// CHECK-NEXT: 12: [B1.2] (Lifetime ends) +// CHECK-NEXT: 7: [B1.6].~A() (Implicit destructor) +// CHECK-NEXT: 8: [B1.6] (Lifetime ends) +// CHECK-NEXT: 9: [B1.4].~A() (Implicit destructor) +// CHECK-NEXT: 10: [B1.4] (Lifetime ends) +// CHECK-NEXT: 11: (CXXConstructExpr, [B1.12], A) +// CHECK-NEXT: 12: A b; +// CHECK-NEXT: 13: [B1.12].~A() (Implicit destructor) +// CHECK-NEXT: 14: [B1.12] (Lifetime ends) +// CHECK-NEXT: 15: [B1.2].~A() (Implicit destructor) +// CHECK-NEXT: 16: [B1.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B0 // CHECK: [B0 (EXIT)] @@ -132,30 +146,34 @@ void test_scope() { // CHECK: [B4 (ENTRY)] // CHECK-NEXT: Succs (1): B3 // CHECK: [B1] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], A) // CHECK-NEXT: 2: A c; -// CHECK-NEXT: 3: [B1.2] (Lifetime ends) -// CHECK-NEXT: 4: [B3.4] (Lifetime ends) -// CHECK-NEXT: 5: [B3.2] (Lifetime ends) +// CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B1.2] (Lifetime ends) +// CHECK-NEXT: 5: [B3.4].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B3.4] (Lifetime ends) +// CHECK-NEXT: 7: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 8: [B3.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B3 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] // CHECK-NEXT: 1: return; -// CHECK-NEXT: 2: [B3.4] (Lifetime ends) -// CHECK-NEXT: 3: [B3.2] (Lifetime ends) +// CHECK-NEXT: 2: [B3.4].~A() (Implicit destructor) +// CHECK-NEXT: 3: [B3.4] (Lifetime ends) +// CHECK-NEXT: 4: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 5: [B3.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B3 // CHECK-NEXT: Succs (1): B0 // CHECK: [B3] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], A) // CHECK-NEXT: 2: A a; -// CHECK-NEXT: 3: (CXXConstructExpr, A) +// CHECK-NEXT: 3: (CXXConstructExpr, [B3.4], A) // CHECK-NEXT: 4: A b; // CHECK-NEXT: 5: UV // CHECK-NEXT: 6: [B3.5] (ImplicitCastExpr, LValueToRValue, _Bool) // CHECK-NEXT: T: if [B3.6] // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (2): B2 B1 - // CHECK: [B0 (EXIT)] // CHECK-NEXT: Preds (2): B1 B2 void test_return() { @@ -169,28 +187,32 @@ void test_return() { // CHECK: [B5 (ENTRY)] // CHECK-NEXT: Succs (1): B4 // CHECK: [B1] -// CHECK-NEXT: 1: [B4.6] (Lifetime ends) -// CHECK-NEXT: 2: [B4.2] (Lifetime ends) +// CHECK-NEXT: 1: [B4.6].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B4.6] (Lifetime ends) +// CHECK-NEXT: 3: [B4.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B4.2] (Lifetime ends) // CHECK-NEXT: Preds (2): B2 B3 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B2.2], A) // CHECK-NEXT: 2: A c; -// CHECK-NEXT: 3: [B2.2] (Lifetime ends) +// CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B2.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B1 // CHECK: [B3] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], A) // CHECK-NEXT: 2: A c; -// CHECK-NEXT: 3: [B3.2] (Lifetime ends) +// CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B3.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B1 // CHECK: [B4] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B4.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: 3: a // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, NoOp, const A) -// CHECK-NEXT: 5: [B4.4] (CXXConstructExpr, A) +// CHECK-NEXT: 5: [B4.4] (CXXConstructExpr, [B4.6], A) // CHECK-NEXT: 6: A b = a; // CHECK-NEXT: 7: b // CHECK-NEXT: 8: [B4.7] (ImplicitCastExpr, NoOp, const class A) @@ -214,29 +236,37 @@ void test_if_implicit_scope() { // CHECK: [B9 (ENTRY)] // CHECK-NEXT: Succs (1): B8 // CHECK: [B1] -// CHECK-NEXT: 1: [B8.6] (Lifetime ends) -// CHECK-NEXT: 2: (CXXConstructExpr, A) -// CHECK-NEXT: 3: A e; -// CHECK-NEXT: 4: [B1.3] (Lifetime ends) -// CHECK-NEXT: 5: [B8.2] (Lifetime ends) +// CHECK-NEXT: 1: [B8.6].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B8.6] (Lifetime ends) +// CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], A) +// CHECK-NEXT: 4: A e; +// CHECK-NEXT: 5: [B1.4].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B1.4] (Lifetime ends) +// CHECK-NEXT: 7: [B8.2].~A() (Implicit destructor) +// CHECK-NEXT: 8: [B8.2] (Lifetime ends) // CHECK-NEXT: Preds (2): B2 B5 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B2.2], A) // CHECK-NEXT: 2: A d; -// CHECK-NEXT: 3: [B2.2] (Lifetime ends) -// CHECK-NEXT: 4: [B4.2] (Lifetime ends) +// CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B2.2] (Lifetime ends) +// CHECK-NEXT: 5: [B4.2].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B4.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B1 // CHECK: [B3] // CHECK-NEXT: 1: return; -// CHECK-NEXT: 2: [B4.2] (Lifetime ends) -// CHECK-NEXT: 3: [B8.6] (Lifetime ends) -// CHECK-NEXT: 4: [B8.2] (Lifetime ends) +// CHECK-NEXT: 2: [B4.2].~A() (Implicit destructor) +// CHECK-NEXT: 3: [B4.2] (Lifetime ends) +// CHECK-NEXT: 4: [B8.6].~A() (Implicit destructor) +// CHECK-NEXT: 5: [B8.6] (Lifetime ends) +// CHECK-NEXT: 6: [B8.2].~A() (Implicit destructor) +// CHECK-NEXT: 7: [B8.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B0 // CHECK: [B4] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B4.2], A) // CHECK-NEXT: 2: A c; // CHECK-NEXT: 3: UV // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool) @@ -244,21 +274,26 @@ void test_if_implicit_scope() { // CHECK-NEXT: Preds (1): B8 // CHECK-NEXT: Succs (2): B3 B2 // CHECK: [B5] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B5.2], A) // CHECK-NEXT: 2: A d; -// CHECK-NEXT: 3: [B5.2] (Lifetime ends) -// CHECK-NEXT: 4: [B7.2] (Lifetime ends) +// CHECK-NEXT: 3: [B5.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B5.2] (Lifetime ends) +// CHECK-NEXT: 5: [B7.2].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B7.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (1): B1 // CHECK: [B6] // CHECK-NEXT: 1: return; -// CHECK-NEXT: 2: [B7.2] (Lifetime ends) -// CHECK-NEXT: 3: [B8.6] (Lifetime ends) -// CHECK-NEXT: 4: [B8.2] (Lifetime ends) +// CHECK-NEXT: 2: [B7.2].~A() (Implicit destructor) +// CHECK-NEXT: 3: [B7.2] (Lifetime ends) +// CHECK-NEXT: 4: [B8.6].~A() (Implicit destructor) +// CHECK-NEXT: 5: [B8.6] (Lifetime ends) +// CHECK-NEXT: 6: [B8.2].~A() (Implicit destructor) +// CHECK-NEXT: 7: [B8.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (1): B0 // CHECK: [B7] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B7.2], A) // CHECK-NEXT: 2: A c; // CHECK-NEXT: 3: UV // CHECK-NEXT: 4: [B7.3] (ImplicitCastExpr, LValueToRValue, _Bool) @@ -266,11 +301,11 @@ void test_if_implicit_scope() { // CHECK-NEXT: Preds (1): B8 // CHECK-NEXT: Succs (2): B6 B5 // CHECK: [B8] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B8.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: 3: a // CHECK-NEXT: 4: [B8.3] (ImplicitCastExpr, NoOp, const A) -// CHECK-NEXT: 5: [B8.4] (CXXConstructExpr, A) +// CHECK-NEXT: 5: [B8.4] (CXXConstructExpr, [B8.6], A) // CHECK-NEXT: 6: A b = a; // CHECK-NEXT: 7: b // CHECK-NEXT: 8: [B8.7] (ImplicitCastExpr, NoOp, const class A) @@ -302,24 +337,28 @@ void test_if_jumps() { // CHECK: [B6 (ENTRY)] // CHECK-NEXT: Succs (1): B5 // CHECK: [B1] -// CHECK-NEXT: 1: [B4.4] (Lifetime ends) -// CHECK-NEXT: 2: [B5.2] (Lifetime ends) +// CHECK-NEXT: 1: [B4.4].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B4.4] (Lifetime ends) +// CHECK-NEXT: 3: [B5.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B5.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] // CHECK-NEXT: Preds (1): B3 // CHECK-NEXT: Succs (1): B4 // CHECK: [B3] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], A) // CHECK-NEXT: 2: A c; -// CHECK-NEXT: 3: [B3.2] (Lifetime ends) -// CHECK-NEXT: 4: [B4.4] (Lifetime ends) +// CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B3.2] (Lifetime ends) +// CHECK-NEXT: 5: [B4.4].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B4.4] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B2 // CHECK: [B4] // CHECK-NEXT: 1: a // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const A) -// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, A) +// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], A) // CHECK-NEXT: 4: A b = a; // CHECK-NEXT: 5: b // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) @@ -331,7 +370,7 @@ void test_if_jumps() { // CHECK-NEXT: Preds (2): B2 B5 // CHECK-NEXT: Succs (2): B3 B1 // CHECK: [B5] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B5.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: Preds (1): B6 // CHECK-NEXT: Succs (1): B4 @@ -346,29 +385,38 @@ void test_while_implicit_scope() { // CHECK: [B12 (ENTRY)] // CHECK-NEXT: Succs (1): B11 // CHECK: [B1] -// CHECK-NEXT: 1: [B10.4] (Lifetime ends) -// CHECK-NEXT: 2: (CXXConstructExpr, A) -// CHECK-NEXT: 3: A e; -// CHECK-NEXT: 4: [B1.3] (Lifetime ends) -// CHECK-NEXT: 5: [B11.2] (Lifetime ends) +// CHECK-NEXT: 1: [B10.4].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B10.4] (Lifetime ends) +// CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], A) +// CHECK-NEXT: 4: A e; +// CHECK-NEXT: 5: [B1.4].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B1.4] (Lifetime ends) +// CHECK-NEXT: 7: [B11.2].~A() (Implicit destructor) +// CHECK-NEXT: 8: [B11.2] (Lifetime ends) // CHECK-NEXT: Preds (2): B8 B10 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] // CHECK-NEXT: Preds (2): B3 B6 // CHECK-NEXT: Succs (1): B10 // CHECK: [B3] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], A) // CHECK-NEXT: 2: A d; -// CHECK-NEXT: 3: [B3.2] (Lifetime ends) -// CHECK-NEXT: 4: [B9.2] (Lifetime ends) -// CHECK-NEXT: 5: [B10.4] (Lifetime ends) +// CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B3.2] (Lifetime ends) +// CHECK-NEXT: 5: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B9.2] (Lifetime ends) +// CHECK-NEXT: 7: [B10.4].~A() (Implicit destructor) +// CHECK-NEXT: 8: [B10.4] (Lifetime ends) // CHECK-NEXT: Preds (1): B5 // CHECK-NEXT: Succs (1): B2 // CHECK: [B4] // CHECK-NEXT: 1: return; -// CHECK-NEXT: 2: [B9.2] (Lifetime ends) -// CHECK-NEXT: 3: [B10.4] (Lifetime ends) -// CHECK-NEXT: 4: [B11.2] (Lifetime ends) +// CHECK-NEXT: 2: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 3: [B9.2] (Lifetime ends) +// CHECK-NEXT: 4: [B10.4].~A() (Implicit destructor) +// CHECK-NEXT: 5: [B10.4] (Lifetime ends) +// CHECK-NEXT: 6: [B11.2].~A() (Implicit destructor) +// CHECK-NEXT: 7: [B11.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B5 // CHECK-NEXT: Succs (1): B0 // CHECK: [B5] @@ -378,8 +426,10 @@ void test_while_implicit_scope() { // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (2): B4 B3 // CHECK: [B6] -// CHECK-NEXT: 1: [B9.2] (Lifetime ends) -// CHECK-NEXT: 2: [B10.4] (Lifetime ends) +// CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B9.2] (Lifetime ends) +// CHECK-NEXT: 3: [B10.4].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B10.4] (Lifetime ends) // CHECK-NEXT: T: continue; // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (1): B2 @@ -390,12 +440,13 @@ void test_while_implicit_scope() { // CHECK-NEXT: Preds (1): B9 // CHECK-NEXT: Succs (2): B6 B5 // CHECK: [B8] -// CHECK-NEXT: 1: [B9.2] (Lifetime ends) +// CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B9.2] (Lifetime ends) // CHECK-NEXT: T: break; // CHECK-NEXT: Preds (1): B9 // CHECK-NEXT: Succs (1): B1 // CHECK: [B9] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B9.2], A) // CHECK-NEXT: 2: A c; // CHECK-NEXT: 3: UV // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) @@ -405,7 +456,7 @@ void test_while_implicit_scope() { // CHECK: [B10] // CHECK-NEXT: 1: a // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const A) -// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, A) +// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], A) // CHECK-NEXT: 4: A b = a; // CHECK-NEXT: 5: b // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) @@ -417,7 +468,7 @@ void test_while_implicit_scope() { // CHECK-NEXT: Preds (2): B2 B11 // CHECK-NEXT: Succs (2): B9 B1 // CHECK: [B11] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B11.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: Preds (1): B12 // CHECK-NEXT: Succs (1): B10 @@ -441,10 +492,12 @@ void test_while_jumps() { // CHECK: [B12 (ENTRY)] // CHECK-NEXT: Succs (1): B11 // CHECK: [B1] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], A) // CHECK-NEXT: 2: A d; -// CHECK-NEXT: 3: [B1.2] (Lifetime ends) -// CHECK-NEXT: 4: [B11.2] (Lifetime ends) +// CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B1.2] (Lifetime ends) +// CHECK-NEXT: 5: [B11.2].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B11.2] (Lifetime ends) // CHECK-NEXT: Preds (2): B8 B2 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] @@ -454,16 +507,20 @@ void test_while_jumps() { // CHECK-NEXT: Preds (2): B3 B6 // CHECK-NEXT: Succs (2): B10 B1 // CHECK: [B3] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], A) // CHECK-NEXT: 2: A c; -// CHECK-NEXT: 3: [B3.2] (Lifetime ends) -// CHECK-NEXT: 4: [B9.2] (Lifetime ends) +// CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B3.2] (Lifetime ends) +// CHECK-NEXT: 5: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B9.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B5 // CHECK-NEXT: Succs (1): B2 // CHECK: [B4] // CHECK-NEXT: 1: return; -// CHECK-NEXT: 2: [B9.2] (Lifetime ends) -// CHECK-NEXT: 3: [B11.2] (Lifetime ends) +// CHECK-NEXT: 2: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 3: [B9.2] (Lifetime ends) +// CHECK-NEXT: 4: [B11.2].~A() (Implicit destructor) +// CHECK-NEXT: 5: [B11.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B5 // CHECK-NEXT: Succs (1): B0 // CHECK: [B5] @@ -473,7 +530,8 @@ void test_while_jumps() { // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (2): B4 B3 // CHECK: [B6] -// CHECK-NEXT: 1: [B9.2] (Lifetime ends) +// CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B9.2] (Lifetime ends) // CHECK-NEXT: T: continue; // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (1): B2 @@ -484,12 +542,13 @@ void test_while_jumps() { // CHECK-NEXT: Preds (1): B9 // CHECK-NEXT: Succs (2): B6 B5 // CHECK: [B8] -// CHECK-NEXT: 1: [B9.2] (Lifetime ends) +// CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B9.2] (Lifetime ends) // CHECK-NEXT: T: break; // CHECK-NEXT: Preds (1): B9 // CHECK-NEXT: Succs (1): B1 // CHECK: [B9] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B9.2], A) // CHECK-NEXT: 2: A b; // CHECK-NEXT: 3: UV // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) @@ -500,7 +559,7 @@ void test_while_jumps() { // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B9 // CHECK: [B11] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B11.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: Preds (1): B12 // CHECK-NEXT: Succs (1): B9 @@ -524,26 +583,30 @@ void test_do_jumps() { // CHECK: [B6 (ENTRY)] // CHECK-NEXT: Succs (1): B5 // CHECK: [B1] -// CHECK-NEXT: 1: [B4.4] (Lifetime ends) -// CHECK-NEXT: 2: [B5.2] (Lifetime ends) +// CHECK-NEXT: 1: [B4.4].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B4.4] (Lifetime ends) +// CHECK-NEXT: 3: [B5.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B5.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] // CHECK-NEXT: 1: b // CHECK-NEXT: 2: [B2.1].p -// CHECK-NEXT: 3: [B4.4] (Lifetime ends) +// CHECK-NEXT: 3: [B4.4].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B4.4] (Lifetime ends) // CHECK-NEXT: Preds (1): B3 // CHECK-NEXT: Succs (1): B4 // CHECK: [B3] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], A) // CHECK-NEXT: 2: A c; -// CHECK-NEXT: 3: [B3.2] (Lifetime ends) +// CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B3.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B4 // CHECK-NEXT: Succs (1): B2 // CHECK: [B4] // CHECK-NEXT: 1: a // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const A) -// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, A) +// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], A) // CHECK-NEXT: 4: A b = a; // CHECK-NEXT: 5: b // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) @@ -555,7 +618,7 @@ void test_do_jumps() { // CHECK-NEXT: Preds (2): B2 B5 // CHECK-NEXT: Succs (2): B3 B1 // CHECK: [B5] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B5.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: Preds (1): B6 // CHECK-NEXT: Succs (1): B4 @@ -569,31 +632,42 @@ void test_for_implicit_scope() { // CHECK: [B12 (ENTRY)] // CHECK-NEXT: Succs (1): B11 // CHECK: [B1] -// CHECK-NEXT: 1: [B10.4] (Lifetime ends) -// CHECK-NEXT: 2: [B11.4] (Lifetime ends) -// CHECK-NEXT: 3: (CXXConstructExpr, A) -// CHECK-NEXT: 4: A f; -// CHECK-NEXT: 5: [B1.4] (Lifetime ends) -// CHECK-NEXT: 6: [B11.2] (Lifetime ends) +// CHECK-NEXT: 1: [B10.4].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B10.4] (Lifetime ends) +// CHECK-NEXT: 3: [B11.4].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B11.4] (Lifetime ends) +// CHECK-NEXT: 5: (CXXConstructExpr, [B1.6], A) +// CHECK-NEXT: 6: A f; +// CHECK-NEXT: 7: [B1.6].~A() (Implicit destructor) +// CHECK-NEXT: 8: [B1.6] (Lifetime ends) +// CHECK-NEXT: 9: [B11.2].~A() (Implicit destructor) +// CHECK-NEXT: 10: [B11.2] (Lifetime ends) // CHECK-NEXT: Preds (2): B8 B10 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] -// CHECK-NEXT: 1: [B10.4] (Lifetime ends) +// CHECK-NEXT: 1: [B10.4].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B10.4] (Lifetime ends) // CHECK-NEXT: Preds (2): B3 B6 // CHECK-NEXT: Succs (1): B10 // CHECK: [B3] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B3.2], A) // CHECK-NEXT: 2: A e; -// CHECK-NEXT: 3: [B3.2] (Lifetime ends) -// CHECK-NEXT: 4: [B9.2] (Lifetime ends) +// CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B3.2] (Lifetime ends) +// CHECK-NEXT: 5: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 6: [B9.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B5 // CHECK-NEXT: Succs (1): B2 // CHECK: [B4] // CHECK-NEXT: 1: return; -// CHECK-NEXT: 2: [B9.2] (Lifetime ends) -// CHECK-NEXT: 3: [B10.4] (Lifetime ends) -// CHECK-NEXT: 4: [B11.4] (Lifetime ends) -// CHECK-NEXT: 5: [B11.2] (Lifetime ends) +// CHECK-NEXT: 2: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 3: [B9.2] (Lifetime ends) +// CHECK-NEXT: 4: [B10.4].~A() (Implicit destructor) +// CHECK-NEXT: 5: [B10.4] (Lifetime ends) +// CHECK-NEXT: 6: [B11.4].~A() (Implicit destructor) +// CHECK-NEXT: 7: [B11.4] (Lifetime ends) +// CHECK-NEXT: 8: [B11.2].~A() (Implicit destructor) +// CHECK-NEXT: 9: [B11.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B5 // CHECK-NEXT: Succs (1): B0 // CHECK: [B5] @@ -603,7 +677,8 @@ void test_for_implicit_scope() { // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (2): B4 B3 // CHECK: [B6] -// CHECK-NEXT: 1: [B9.2] (Lifetime ends) +// CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B9.2] (Lifetime ends) // CHECK-NEXT: T: continue; // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (1): B2 @@ -614,12 +689,13 @@ void test_for_implicit_scope() { // CHECK-NEXT: Preds (1): B9 // CHECK-NEXT: Succs (2): B6 B5 // CHECK: [B8] -// CHECK-NEXT: 1: [B9.2] (Lifetime ends) +// CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B9.2] (Lifetime ends) // CHECK-NEXT: T: break; // CHECK-NEXT: Preds (1): B9 // CHECK-NEXT: Succs (1): B1 // CHECK: [B9] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B9.2], A) // CHECK-NEXT: 2: A d; // CHECK-NEXT: 3: UV // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) @@ -629,7 +705,7 @@ void test_for_implicit_scope() { // CHECK: [B10] // CHECK-NEXT: 1: b // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const A) -// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, A) +// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], A) // CHECK-NEXT: 4: A c = b; // CHECK-NEXT: 5: c // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) @@ -641,9 +717,9 @@ void test_for_implicit_scope() { // CHECK-NEXT: Preds (2): B2 B11 // CHECK-NEXT: Succs (2): B9 B1 // CHECK: [B11] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B11.2], A) // CHECK-NEXT: 2: A a; -// CHECK-NEXT: 3: (CXXConstructExpr, A) +// CHECK-NEXT: 3: (CXXConstructExpr, [B11.4], A) // CHECK-NEXT: 4: A b; // CHECK-NEXT: Preds (1): B12 // CHECK-NEXT: Succs (1): B10 @@ -667,13 +743,16 @@ void test_for_jumps() { // CHECK: [B9 (ENTRY)] // CHECK-NEXT: Succs (1): B8 // CHECK: [B1] -// CHECK-NEXT: 1: [B7.4] (Lifetime ends) -// CHECK-NEXT: 2: [B8.2] (Lifetime ends) +// CHECK-NEXT: 1: [B7.4].~A() (Implicit destructor) +// CHECK-NEXT: 2: [B7.4] (Lifetime ends) +// CHECK-NEXT: 3: [B8.2].~A() (Implicit destructor) +// CHECK-NEXT: 4: [B8.2] (Lifetime ends) // CHECK-NEXT: Preds (1): B7 // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] // CHECK-NEXT: 1: [B5.4] ? [B3.3] : [B4.2] -// CHECK-NEXT: 2: [B7.4] (Lifetime ends) +// CHECK-NEXT: 2: [B7.4].~A() (Implicit destructor) +// CHECK-NEXT: 3: [B7.4] (Lifetime ends) // CHECK-NEXT: Preds (2): B3 B4 // CHECK-NEXT: Succs (1): B7 // CHECK: [B3] @@ -703,7 +782,7 @@ void test_for_jumps() { // CHECK: [B7] // CHECK-NEXT: 1: a // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, NoOp, const A) -// CHECK-NEXT: 3: [B7.2] (CXXConstructExpr, A) +// CHECK-NEXT: 3: [B7.2] (CXXConstructExpr, [B7.4], A) // CHECK-NEXT: 4: A b = a; // CHECK-NEXT: 5: b // CHECK-NEXT: 6: [B7.5] (ImplicitCastExpr, NoOp, const class A) @@ -715,7 +794,7 @@ void test_for_jumps() { // CHECK-NEXT: Preds (2): B2 B8 // CHECK-NEXT: Succs (2): B6 B1 // CHECK: [B8] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B8.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: Preds (1): B9 // CHECK-NEXT: Succs (1): B7 @@ -727,7 +806,7 @@ void test_for_inc_conditional() { // CHECK: [B2 (ENTRY)] // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] -// CHECK-NEXT: 1: (CXXConstructExpr, A) +// CHECK-NEXT: 1: (CXXConstructExpr, [B1.2], A) // CHECK-NEXT: 2: A a; // CHECK-NEXT: 3: int n; // CHECK-NEXT: 4: n @@ -735,8 +814,9 @@ void test_for_inc_conditional() { // CHECK-NEXT: 6: a // CHECK-NEXT: 7: [B1.6].p // CHECK-NEXT: 8: [B1.7] = [B1.5] -// CHECK-NEXT: 9: [B1.2] (Lifetime ends) -// CHECK-NEXT: 10: [B1.3] (Lifetime ends) +// CHECK-NEXT: 9: [B1.2].~A() (Implicit destructor) +// CHECK-NEXT: 10: [B1.2] (Lifetime ends) +// CHECK-NEXT: 11: [B1.3] (Lifetime ends) // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B0 // CHECK: [B0 (EXIT)] @@ -819,15 +899,17 @@ struct B { // CHECK: [B1] // CHECK-NEXT: 1: i // CHECK-NEXT: 2: [B1.1]++ -// CHECK-NEXT: 3: [B2.4] (Lifetime ends) -// CHECK-NEXT: 4: [B2.2] (Lifetime ends) -// CHECK-NEXT: 5: [B3.1] (Lifetime ends) +// CHECK-NEXT: 3: [B2.4].~B() (Implicit destructor) +// CHECK-NEXT: 4: [B2.4] (Lifetime ends) +// CHECK-NEXT: 5: [B2.2].~B() (Implicit destructor) +// CHECK-NEXT: 6: [B2.2] (Lifetime ends) +// CHECK-NEXT: 7: [B3.1] (Lifetime ends) // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] // CHECK-NEXT: label: -// CHECK-NEXT: 1: (CXXConstructExpr, B) +// CHECK-NEXT: 1: (CXXConstructExpr, [B2.2], B) // CHECK-NEXT: 2: B b1; -// CHECK-NEXT: 3: (CXXConstructExpr, B) +// CHECK-NEXT: 3: (CXXConstructExpr, [B2.4], B) // CHECK-NEXT: 4: B b2; // CHECK-NEXT: Preds (2): B3 B4 // CHECK-NEXT: Succs (1): B4 @@ -836,8 +918,10 @@ struct B { // CHECK-NEXT: Preds (1): B5 // CHECK-NEXT: Succs (1): B2 // CHECK: [B4] -// CHECK-NEXT: 1: [B2.4] (Lifetime ends) -// CHECK-NEXT: 2: [B2.2] (Lifetime ends) +// CHECK-NEXT: 1: [B2.4].~B() (Implicit destructor) +// CHECK-NEXT: 2: [B2.4] (Lifetime ends) +// CHECK-NEXT: 3: [B2.2].~B() (Implicit destructor) +// CHECK-NEXT: 4: [B2.2] (Lifetime ends) // CHECK-NEXT: T: goto label; // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B2