From d9839346b97a232b56335f681bf507bbc7d39e33 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Thu, 15 Feb 2018 03:13:36 +0000 Subject: [PATCH] [CFG] Provide construction contexts for temproary objects. Constructors of C++ temporary objects that have destructors now can be queried to discover that they're indeed constructing temporary objects. The respective CXXBindTemporaryExpr, which is also repsonsible for destroying the temporary at the end of full-expression, is now available at the construction site in the CFG. This is all the context we need to provide for temporary objects that are not lifetime extended. For lifetime-extended temporaries, more context is necessary. Differential Revision: https://reviews.llvm.org/D43056 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325210 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFG.cpp | 4 +- test/Analysis/auto-obj-dtors-cfg-output.cpp | 3 +- test/Analysis/cfg-rich-constructors.cpp | 143 ++++++++++++++- test/Analysis/temp-obj-dtors-cfg-output.cpp | 183 +++++++++++++------- 4 files changed, 267 insertions(+), 66 deletions(-) diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 9fe9ad11bf..d2d1917c46 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -3923,6 +3923,8 @@ CFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E, autoCreateBlock(); appendStmt(Block, E); + EnterConstructionContextIfNecessary(E, E->getSubExpr()); + // We do not want to propagate the AlwaysAdd property. asc = asc.withAlwaysAdd(false); } @@ -3992,7 +3994,7 @@ CFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E, CFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, AddStmtChoice asc) { autoCreateBlock(); - appendStmt(Block, C); + appendConstructor(Block, C); return VisitChildren(C); } diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp index 843ccd3bd4..42e648312f 100644 --- a/test/Analysis/auto-obj-dtors-cfg-output.cpp +++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp @@ -49,7 +49,8 @@ extern const bool UV; // CHECK-NEXT: 3: a // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class A) // CHECK-NEXT: 5: const A &b = a; -// CHECK-NEXT: 6: A() (CXXConstructExpr, class A) +// WARNINGS-NEXT: 6: A() (CXXConstructExpr, class A) +// ANALYZER-NEXT: 6: A() (CXXConstructExpr, [B1.7], class A) // CHECK-NEXT: 7: [B1.6] (BindTemporary) // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A) // CHECK-NEXT: 9: [B1.8] diff --git a/test/Analysis/cfg-rich-constructors.cpp b/test/Analysis/cfg-rich-constructors.cpp index 46125f729f..5818912d26 100644 --- a/test/Analysis/cfg-rich-constructors.cpp +++ b/test/Analysis/cfg-rich-constructors.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1 +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 -w %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s class C { @@ -8,6 +8,7 @@ public: C(int, int); static C get(); + operator bool() const; }; typedef __typeof(sizeof(int)) size_t; @@ -226,7 +227,7 @@ public: } // end namespace ctor_initializers -namespace return_stmt { +namespace return_stmt_without_dtor { // CHECK: C returnVariable() // CHECK: 1: (CXXConstructExpr, [B1.2], class C) @@ -315,4 +316,140 @@ C returnChainOfCopies() { return C(C::get()); } -} // end namespace return_stmt +} // end namespace return_stmt_without_dtor + +namespace return_stmt_with_dtor { + +class D { +public: + D(); + ~D(); +}; + +// CHECK: return_stmt_with_dtor::D returnTemporary() +// CHECK: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], class return_stmt_with_dtor::D) +// CHECK-NEXT: 2: [B1.1] (BindTemporary) +// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D) +// CHECK-NEXT: 4: [B1.3] +// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class return_stmt_with_dtor::D) +// CHECK-NEXT: 6: ~return_stmt_with_dtor::D() (Temporary object destructor) +// CHECK-NEXT: 7: return [B1.5]; +D returnTemporary() { + return D(); +} + +} // end namespace return_stmt_with_dtor + +namespace temporary_object_expr_without_dtors { + +// TODO: Should provide construction context for the constructor, +// even if there is no specific trigger statement here. +// CHECK: void simpleTemporary() +// CHECK 1: C() (CXXConstructExpr, class C) +void simpleTemporary() { + C(); +} + +// TODO: Should provide construction context for the constructor, +// CHECK: void temporaryInCondition() +// CHECK: 1: C() (CXXConstructExpr, class C) +// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, NoOp, const class C) +// CHECK-NEXT: 3: [B2.2].operator bool +// CHECK-NEXT: 4: [B2.2] +// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CHECK-NEXT: T: if [B2.5] +void temporaryInCondition() { + if (C()); +} + +} // end namespace temporary_object_expr_without_dtors + +namespace temporary_object_expr_with_dtors { + +class D { +public: + D(); + D(int); + ~D(); + + static D get(); + + operator bool() const; +}; + +// CHECK: void simpleTemporary() +// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 2: [B1.1] (BindTemporary) +// CHECK-NEXT: 3: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) +void simpleTemporary() { + D(); +} + +// CHECK: void temporaryInCondition() +// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 2: [B2.1] (BindTemporary) +// CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 4: [B2.3].operator bool +// CHECK-NEXT: 5: [B2.3] +// CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CHECK-NEXT: 7: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) +// CHECK-NEXT: T: if [B2.6] +void temporaryInCondition() { + if (D()); +} + +// CHECK: void referenceVariableWithConstructor() +// CHECK: 1: 0 +// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 3: [B1.2] (BindTemporary) +// CHECK-NEXT: 4: [B1.3] +// CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d(0); +// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor) +void referenceVariableWithConstructor() { + const D &d(0); +} + +// CHECK: void referenceVariableWithInitializer() +// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 2: [B1.1] (BindTemporary) +// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 4: [B1.3] +// CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d = temporary_object_expr_with_dtors::D(); +// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor) +void referenceVariableWithInitializer() { + const D &d = D(); +} + +// CHECK: void referenceVariableWithTernaryOperator(bool coin) +// CHECK: [B4] +// CHECK-NEXT: 1: [B7.2] ? [B5.8] : [B6.8] +// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 3: [B4.2] +// CHECK-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0); +// CHECK-NEXT: T: (Temp Dtor) [B6.3] +// CHECK: [B5] +// CHECK-NEXT: 1: D::get +// CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void)) +// CHECK-NEXT: 3: [B5.2]() +// CHECK-NEXT: 4: [B5.3] (BindTemporary) +// CHECK-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 6: [B5.5] +// CHECK-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 8: [B5.7] (BindTemporary) +// CHECK: [B6] +// CHECK-NEXT: 1: 0 +// CHECK-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 3: [B6.2] (BindTemporary) +// CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 6: [B6.5] +// CHECK-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 8: [B6.7] (BindTemporary) +// CHECK: [B7] +// CHECK-NEXT: 1: coin +// CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) +// CHECK-NEXT: T: [B7.2] ? ... : ... +void referenceVariableWithTernaryOperator(bool coin) { + const D &d = coin ? D::get() : D(0); +} +} // end namespace temporary_object_expr_with_dtors diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp index 1ddf877861..6750f77a8c 100644 --- a/test/Analysis/temp-obj-dtors-cfg-output.cpp +++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp @@ -216,7 +216,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B2 (ENTRY)] // CHECK: Succs (1): B1 // CHECK: [B1] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A) // CHECK: 2: [B1.1] (BindTemporary) // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B1.3] @@ -275,7 +276,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B2 (ENTRY)] // CHECK: Succs (1): B1 // CHECK: [B1] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A) // CHECK: 2: [B1.1] (BindTemporary) // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B1.3] @@ -290,13 +292,15 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B2 (ENTRY)] // CHECK: Succs (1): B1 // CHECK: [B1] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A) // CHECK: 2: [B1.1] (BindTemporary) // CHECK: 3: [B1.2].operator int // CHECK: 4: [B1.2] // CHECK: 5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int) // CHECK: 6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int) -// CHECK: 7: B() (CXXConstructExpr, class B) +// WARNINGS: 7: B() (CXXConstructExpr, class B) +// ANALYZER: 7: B() (CXXConstructExpr, [B1.8], class B) // CHECK: 8: [B1.7] (BindTemporary) // CHECK: 9: [B1.8].operator int // CHECK: 10: [B1.8] @@ -308,13 +312,15 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: 16: ~A() (Temporary object destructor) // CHECK: 17: foo // CHECK: 18: [B1.17] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int)) -// CHECK: 19: A() (CXXConstructExpr, class A) +// WARNINGS: 19: A() (CXXConstructExpr, class A) +// ANALYZER: 19: A() (CXXConstructExpr, [B1.20], class A) // CHECK: 20: [B1.19] (BindTemporary) // CHECK: 21: [B1.20].operator int // CHECK: 22: [B1.20] // CHECK: 23: [B1.22] (ImplicitCastExpr, UserDefinedConversion, int) // CHECK: 24: int([B1.23]) (CXXFunctionalCastExpr, NoOp, int) -// CHECK: 25: B() (CXXConstructExpr, class B) +// WARNINGS: 25: B() (CXXConstructExpr, class B) +// ANALYZER: 25: B() (CXXConstructExpr, [B1.26], class B) // CHECK: 26: [B1.25] (BindTemporary) // CHECK: 27: [B1.26].operator int // CHECK: 28: [B1.26] @@ -347,7 +353,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (2): B4 B5 // CHECK: Succs (2): B2 B1 // CHECK: [B4] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B4.2], class B) // CHECK: 2: [B4.1] (BindTemporary) // CHECK: 3: [B4.2].operator bool // CHECK: 4: [B4.2] @@ -358,7 +365,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: 1: ~A() (Temporary object destructor) // CHECK: 2: foo // CHECK: 3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool)) -// CHECK: 4: A() (CXXConstructExpr, class A) +// WARNINGS: 4: A() (CXXConstructExpr, class A) +// ANALYZER: 4: A() (CXXConstructExpr, [B5.5], class A) // CHECK: 5: [B5.4] (BindTemporary) // CHECK: 6: [B5.5].operator bool // CHECK: 7: [B5.5] @@ -377,7 +385,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (2): B8 B9 // CHECK: Succs (2): B6 B5 // CHECK: [B8] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B8.2], class B) // CHECK: 2: [B8.1] (BindTemporary) // CHECK: 3: [B8.2].operator bool // CHECK: 4: [B8.2] @@ -385,7 +394,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (1): B9 // CHECK: Succs (1): B7 // CHECK: [B9] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B9.2], class A) // CHECK: 2: [B9.1] (BindTemporary) // CHECK: 3: [B9.2].operator bool // CHECK: 4: [B9.2] @@ -413,7 +423,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (2): B4 B5 // CHECK: Succs (2): B2 B1 // CHECK: [B4] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B4.2], class B) // CHECK: 2: [B4.1] (BindTemporary) // CHECK: 3: [B4.2].operator bool // CHECK: 4: [B4.2] @@ -424,7 +435,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: 1: ~A() (Temporary object destructor) // CHECK: 2: foo // CHECK: 3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool)) -// CHECK: 4: A() (CXXConstructExpr, class A) +// WARNINGS: 4: A() (CXXConstructExpr, class A) +// ANALYZER: 4: A() (CXXConstructExpr, [B5.5], class A) // CHECK: 5: [B5.4] (BindTemporary) // CHECK: 6: [B5.5].operator bool // CHECK: 7: [B5.5] @@ -443,7 +455,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (2): B8 B9 // CHECK: Succs (2): B6 B5 // CHECK: [B8] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B8.2], class B) // CHECK: 2: [B8.1] (BindTemporary) // CHECK: 3: [B8.2].operator bool // CHECK: 4: [B8.2] @@ -451,7 +464,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (1): B9 // CHECK: Succs (1): B7 // CHECK: [B9] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B9.2], class A) // CHECK: 2: [B9.1] (BindTemporary) // CHECK: 3: [B9.2].operator bool // CHECK: 4: [B9.2] @@ -484,7 +498,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Succs (1): B1 // CHECK: [B4] // CHECK: 1: ~B() (Temporary object destructor) -// CHECK: 2: B() (CXXConstructExpr, class B) +// WARNINGS: 2: B() (CXXConstructExpr, class B) +// ANALYZER: 2: B() (CXXConstructExpr, [B4.3], class B) // CHECK: 3: [B4.2] (BindTemporary) // CHECK: 4: [B4.3].operator bool // CHECK: 5: [B4.3] @@ -516,16 +531,19 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (2): B8 B9 // CHECK: Succs (2): B6 B5 // CHECK: [B8] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B8.2], class A) // CHECK: 2: [B8.1] (BindTemporary) // CHECK: 3: [B8.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B8.3] -// CHECK: 5: [B8.4] (CXXConstructExpr, class A) +// WARNINGS: 5: [B8.4] (CXXConstructExpr, class A) +// ANALYZER: 5: [B8.4] (CXXConstructExpr, [B8.6], class A) // CHECK: 6: [B8.5] (BindTemporary) // CHECK: Preds (1): B10 // CHECK: Succs (1): B7 // CHECK: [B9] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B9.2], class B) // CHECK: 2: [B9.1] (BindTemporary) // CHECK: 3: [B9.2].operator A // CHECK: 4: [B9.2] @@ -533,17 +551,20 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: 6: [B9.5] (BindTemporary) // CHECK: 7: [B9.6] (ImplicitCastExpr, NoOp, const class A) // CHECK: 8: [B9.7] -// CHECK: 9: [B9.8] (CXXConstructExpr, class A) +// WARNINGS: 9: [B9.8] (CXXConstructExpr, class A) +// ANALYZER: 9: [B9.8] (CXXConstructExpr, [B9.10], class A) // CHECK: 10: [B9.9] (BindTemporary) // CHECK: 11: A([B9.10]) (CXXFunctionalCastExpr, ConstructorConversion, class A) // CHECK: 12: [B9.11] (ImplicitCastExpr, NoOp, const class A) // CHECK: 13: [B9.12] -// CHECK: 14: [B9.13] (CXXConstructExpr, class A) +// WARNINGS: 14: [B9.13] (CXXConstructExpr, class A) +// ANALYZER: 14: [B9.13] (CXXConstructExpr, [B9.15], class A) // CHECK: 15: [B9.14] (BindTemporary) // CHECK: Preds (1): B10 // CHECK: Succs (1): B7 // CHECK: [B10] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B10.2], class B) // CHECK: 2: [B10.1] (BindTemporary) // CHECK: 3: [B10.2].operator bool // CHECK: 4: [B10.2] @@ -610,7 +631,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (1): B3 // CHECK: Succs (1): B0 // CHECK: [B3] -// CHECK: 1: C() (CXXConstructExpr, struct C) +// WARNINGS: 1: C() (CXXConstructExpr, struct C) +// ANALYZER: 1: C() (CXXConstructExpr, [B3.2], struct C) // CHECK: 2: [B3.1] (BindTemporary) // CHECK: 3: [B3.2].operator bool // CHECK: 4: [B3.2] @@ -639,7 +661,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (1): B4 // CHECK: Succs (1): B0 // CHECK: [B4] -// CHECK: 1: C() (CXXConstructExpr, struct C) +// WARNINGS: 1: C() (CXXConstructExpr, struct C) +// ANALYZER: 1: C() (CXXConstructExpr, [B4.2], struct C) // CHECK: 2: [B4.1] (BindTemporary) // CHECK: 3: [B4.2] (ImplicitCastExpr, NoOp, const struct C) // CHECK: 4: [B4.3] @@ -744,16 +767,19 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (2): B5 B6 // CHECK: Succs (2): B3 B2 // CHECK: [B5] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B5.2], class A) // CHECK: 2: [B5.1] (BindTemporary) // CHECK: 3: [B5.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B5.3] -// CHECK: 5: [B5.4] (CXXConstructExpr, class A) +// WARNINGS: 5: [B5.4] (CXXConstructExpr, class A) +// ANALYZER: 5: [B5.4] (CXXConstructExpr, [B5.6], class A) // CHECK: 6: [B5.5] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 // CHECK: [B6] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B6.2], class B) // CHECK: 2: [B6.1] (BindTemporary) // CHECK: 3: [B6.2].operator A // CHECK: 4: [B6.2] @@ -761,12 +787,14 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: 6: [B6.5] (BindTemporary) // CHECK: 7: [B6.6] (ImplicitCastExpr, NoOp, const class A) // CHECK: 8: [B6.7] -// CHECK: 9: [B6.8] (CXXConstructExpr, class A) +// WARNINGS: 9: [B6.8] (CXXConstructExpr, class A) +// ANALYZER: 9: [B6.8] (CXXConstructExpr, [B6.10], class A) // CHECK: 10: [B6.9] (BindTemporary) // CHECK: 11: A([B6.10]) (CXXFunctionalCastExpr, ConstructorConversion, class A) // CHECK: 12: [B6.11] (ImplicitCastExpr, NoOp, const class A) // CHECK: 13: [B6.12] -// CHECK: 14: [B6.13] (CXXConstructExpr, class A) +// WARNINGS: 14: [B6.13] (CXXConstructExpr, class A) +// ANALYZER: 14: [B6.13] (CXXConstructExpr, [B6.15], class A) // CHECK: 15: [B6.14] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 @@ -774,7 +802,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: 1: ~B() (Temporary object destructor) // CHECK: 2: foo // CHECK: 3: [B7.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &)) -// CHECK: 4: B() (CXXConstructExpr, class B) +// WARNINGS: 4: B() (CXXConstructExpr, class B) +// ANALYZER: 4: B() (CXXConstructExpr, [B7.5], class B) // CHECK: 5: [B7.4] (BindTemporary) // CHECK: 6: [B7.5].operator bool // CHECK: 7: [B7.5] @@ -801,16 +830,19 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Preds (2): B11 B12 // CHECK: Succs (2): B9 B8 // CHECK: [B11] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B11.2], class A) // CHECK: 2: [B11.1] (BindTemporary) // CHECK: 3: [B11.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B11.3] -// CHECK: 5: [B11.4] (CXXConstructExpr, class A) +// WARNINGS: 5: [B11.4] (CXXConstructExpr, class A) +// ANALYZER: 5: [B11.4] (CXXConstructExpr, [B11.6], class A) // CHECK: 6: [B11.5] (BindTemporary) // CHECK: Preds (1): B13 // CHECK: Succs (1): B10 // CHECK: [B12] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B12.2], class B) // CHECK: 2: [B12.1] (BindTemporary) // CHECK: 3: [B12.2].operator A // CHECK: 4: [B12.2] @@ -818,17 +850,20 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: 6: [B12.5] (BindTemporary) // CHECK: 7: [B12.6] (ImplicitCastExpr, NoOp, const class A) // CHECK: 8: [B12.7] -// CHECK: 9: [B12.8] (CXXConstructExpr, class A) +// WARNINGS: 9: [B12.8] (CXXConstructExpr, class A) +// ANALYZER: 9: [B12.8] (CXXConstructExpr, [B12.10], class A) // CHECK: 10: [B12.9] (BindTemporary) // CHECK: 11: A([B12.10]) (CXXFunctionalCastExpr, ConstructorConversion, class A) // CHECK: 12: [B12.11] (ImplicitCastExpr, NoOp, const class A) // CHECK: 13: [B12.12] -// CHECK: 14: [B12.13] (CXXConstructExpr, class A) +// WARNINGS: 14: [B12.13] (CXXConstructExpr, class A) +// ANALYZER: 14: [B12.13] (CXXConstructExpr, [B12.15], class A) // CHECK: 15: [B12.14] (BindTemporary) // CHECK: Preds (1): B13 // CHECK: Succs (1): B10 // CHECK: [B13] -// CHECK: 1: B() (CXXConstructExpr, class B) +// WARNINGS: 1: B() (CXXConstructExpr, class B) +// ANALYZER: 1: B() (CXXConstructExpr, [B13.2], class B) // CHECK: 2: [B13.1] (BindTemporary) // CHECK: 3: [B13.2].operator bool // CHECK: 4: [B13.2] @@ -868,24 +903,29 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B5] // CXX98: 1: [B7.2] (ImplicitCastExpr, NoOp, const class A) // CXX98: 2: [B5.1] -// CXX98: 3: [B5.2] (CXXConstructExpr, class A) +// WARNINGS-CXX98: 3: [B5.2] (CXXConstructExpr, class A) +// ANALYZER-CXX98: 3: [B5.2] (CXXConstructExpr, [B5.4], class A) // CXX98: 4: [B5.3] (BindTemporary) // CXX11: 1: [B7.3] (ImplicitCastExpr, NoOp, const class A) -// CXX11: 2: [B5.1] (CXXConstructExpr, class A) +// WARNINGS-CXX11: 2: [B5.1] (CXXConstructExpr, class A) +// ANALYZER-CXX11: 2: [B5.1] (CXXConstructExpr, [B5.3], class A) // CXX11: 3: [B5.2] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 // CHECK: [B6] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B6.2], class A) // CHECK: 2: [B6.1] (BindTemporary) // CHECK: 3: [B6.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B6.3] -// CHECK: 5: [B6.4] (CXXConstructExpr, class A) +// WARNINGS: 5: [B6.4] (CXXConstructExpr, class A) +// ANALYZER: 5: [B6.4] (CXXConstructExpr, [B6.6], class A) // CHECK: 6: [B6.5] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 // CHECK: [B7] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B7.2], class A) // CHECK: 2: [B7.1] (BindTemporary) // CXX98: 3: [B7.2].operator bool // CXX98: 4: [B7.2] @@ -928,26 +968,31 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B5] // CXX98: 1: [B7.4] (ImplicitCastExpr, NoOp, const class A) // CXX98: 2: [B5.1] -// CXX98: 3: [B5.2] (CXXConstructExpr, class A) +// WARNINGS-CXX98: 3: [B5.2] (CXXConstructExpr, class A) +// ANALYZER-CXX98: 3: [B5.2] (CXXConstructExpr, [B5.4], class A) // CXX98: 4: [B5.3] (BindTemporary) // CXX11: 1: [B7.5] (ImplicitCastExpr, NoOp, const class A) -// CXX11: 2: [B5.1] (CXXConstructExpr, class A) +// WARNINGS-CXX11: 2: [B5.1] (CXXConstructExpr, class A) +// ANALYZER-CXX11: 2: [B5.1] (CXXConstructExpr, [B5.3], class A) // CXX11: 3: [B5.2] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 // CHECK: [B6] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B6.2], class A) // CHECK: 2: [B6.1] (BindTemporary) // CHECK: 3: [B6.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B6.3] -// CHECK: 5: [B6.4] (CXXConstructExpr, class A) +// WARNINGS: 5: [B6.4] (CXXConstructExpr, class A) +// ANALYZER: 5: [B6.4] (CXXConstructExpr, [B6.6], class A) // CHECK: 6: [B6.5] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 // CHECK: [B7] // CHECK: 1: foo // CHECK: 2: [B7.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &)) -// CHECK: 3: A() (CXXConstructExpr, class A) +// WARNINGS: 3: A() (CXXConstructExpr, class A) +// ANALYZER: 3: A() (CXXConstructExpr, [B7.4], class A) // CHECK: 4: [B7.3] (BindTemporary) // CXX98: 5: [B7.4].operator bool // CXX98: 6: [B7.4] @@ -976,24 +1021,29 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B10] // CXX98: 1: [B12.2] (ImplicitCastExpr, NoOp, const class A) // CXX98: 2: [B10.1] -// CXX98: 3: [B10.2] (CXXConstructExpr, class A) +// WARNINGS-CXX98: 3: [B10.2] (CXXConstructExpr, class A) +// ANALYZER-CXX98: 3: [B10.2] (CXXConstructExpr, [B10.4], class A) // CXX98: 4: [B10.3] (BindTemporary) // CXX11: 1: [B12.3] (ImplicitCastExpr, NoOp, const class A) -// CXX11: 2: [B10.1] (CXXConstructExpr, class A) +// WARNINGS-CXX11: 2: [B10.1] (CXXConstructExpr, class A) +// ANALYZER-CXX11: 2: [B10.1] (CXXConstructExpr, [B10.3], class A) // CXX11: 3: [B10.2] (BindTemporary) // CHECK: Preds (1): B12 // CHECK: Succs (1): B9 // CHECK: [B11] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS-CHECK: 1: A() (CXXConstructExpr, class A) +// ANALYZER-CHECK: 1: A() (CXXConstructExpr, [B11.2], class A) // CHECK: 2: [B11.1] (BindTemporary) // CHECK: 3: [B11.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B11.3] -// CHECK: 5: [B11.4] (CXXConstructExpr, class A) +// WARNINGS: 5: [B11.4] (CXXConstructExpr, class A) +// ANALYZER: 5: [B11.4] (CXXConstructExpr, [B11.6], class A) // CHECK: 6: [B11.5] (BindTemporary) // CHECK: Preds (1): B12 // CHECK: Succs (1): B9 // CHECK: [B12] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B12.2], class A) // CHECK: 2: [B12.1] (BindTemporary) // CXX98: 3: [B12.2].operator bool // CXX98: 4: [B12.2] @@ -1011,7 +1061,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B2 (ENTRY)] // CHECK: Succs (1): B1 // CHECK: [B1] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A) // CHECK: 2: [B1.1] (BindTemporary) // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B1.3] @@ -1028,14 +1079,16 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B2 (ENTRY)] // CHECK: Succs (1): B1 // CHECK: [B1] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A) // CHECK: 2: [B1.1] (BindTemporary) // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B1.3] // CHECK: 5: const A &a = A(); // CHECK: 6: foo // CHECK: 7: [B1.6] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &)) -// CHECK: 8: A() (CXXConstructExpr, class A) +// WARNINGS: 8: A() (CXXConstructExpr, class A) +// ANALYZER: 8: A() (CXXConstructExpr, [B1.9], class A) // CHECK: 9: [B1.8] (BindTemporary) // CHECK: 10: [B1.9] (ImplicitCastExpr, NoOp, const class A) // CHECK: 11: [B1.10] @@ -1096,7 +1149,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Succs (1): B1 // CHECK: [B1] // CHECK: 1: int a; -// CHECK: 2: A() (CXXConstructExpr, class A) +// WARNINGS: 2: A() (CXXConstructExpr, class A) +// ANALYZER: 2: A() (CXXConstructExpr, [B1.3], class A) // CHECK: 3: [B1.2] (BindTemporary) // CHECK: 4: [B1.3].operator int // CHECK: 5: [B1.3] @@ -1112,13 +1166,15 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B2 (ENTRY)] // CHECK: Succs (1): B1 // CHECK: [B1] -// CHECK: 1: A() (CXXConstructExpr, class A) +// WARNINGS: 1: A() (CXXConstructExpr, class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A) // CHECK: 2: [B1.1] (BindTemporary) // CHECK: 3: [B1.2].operator int // CHECK: 4: [B1.2] // CHECK: 5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int) // CHECK: 6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int) -// CHECK: 7: B() (CXXConstructExpr, class B) +// WARNINGS: 7: B() (CXXConstructExpr, class B) +// ANALYZER: 7: B() (CXXConstructExpr, [B1.8], class B) // CHECK: 8: [B1.7] (BindTemporary) // CHECK: 9: [B1.8].operator int // CHECK: 10: [B1.8] @@ -1142,7 +1198,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Succs (1): B0 // CHECK: [B2 (NORETURN)] // CHECK: 1: int a; -// CHECK: 2: NoReturn() (CXXConstructExpr, class NoReturn) +// WARNINGS: 2: NoReturn() (CXXConstructExpr, class NoReturn) +// ANALYZER: 2: NoReturn() (CXXConstructExpr, [B2.3], class NoReturn) // CHECK: 3: [B2.2] (BindTemporary) // CHECK: [[MEMBER:[45]]]: [B2.{{[34]}}].f // CHECK: {{[56]}}: [B2.[[MEMBER]]]() @@ -1159,7 +1216,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: Succs (1): B0 // CHECK: [B2 (NORETURN)] // CHECK: 1: int a; -// CHECK: 2: NoReturn() (CXXConstructExpr, class NoReturn) +// WARNINGS: 2: NoReturn() (CXXConstructExpr, class NoReturn) +// ANALYZER: 2: NoReturn() (CXXConstructExpr, [B2.3], class NoReturn) // CHECK: 3: [B2.2] (BindTemporary) // CHECK: 4: 47 // CHECK: 5: ... , [B2.4] @@ -1196,7 +1254,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B6] // CHECK: 1: check // CHECK: 2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &)) -// CHECK: 3: NoReturn() (CXXConstructExpr, class NoReturn) +// WARNINGS: 3: NoReturn() (CXXConstructExpr, class NoReturn) +// ANALYZER: 3: NoReturn() (CXXConstructExpr, [B6.4], class NoReturn) // CHECK: 4: [B6.3] (BindTemporary) // CHECK: 5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn) // CHECK: 6: [B6.5] @@ -1246,7 +1305,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B6] // CHECK: 1: check // CHECK: 2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &)) -// CHECK: 3: NoReturn() (CXXConstructExpr, class NoReturn) +// WARNINGS: 3: NoReturn() (CXXConstructExpr, class NoReturn) +// ANALYZER: 3: NoReturn() (CXXConstructExpr, [B6.4], class NoReturn) // CHECK: 4: [B6.3] (BindTemporary) // CHECK: 5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn) // CHECK: 6: [B6.5] @@ -1303,7 +1363,8 @@ int testConsistencyNestedNormalReturn(bool value) { // CHECK: [B6] // CHECK: 1: check // CHECK: 2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &)) -// CHECK: 3: NoReturn() (CXXConstructExpr, class NoReturn) +// WARNINGS: 3: NoReturn() (CXXConstructExpr, class NoReturn) +// ANALYZER: 3: NoReturn() (CXXConstructExpr, [B6.4], class NoReturn) // CHECK: 4: [B6.3] (BindTemporary) // CHECK: 5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn) // CHECK: 6: [B6.5] -- 2.40.0