From: Artem Dergachev Date: Thu, 1 Mar 2018 01:09:24 +0000 (+0000) Subject: [CFG] [analyzer] Recall that we only skip NoOp casts in construction contexts. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d3757b9746eb7017b5b34055286a5d163c79988e;p=clang [CFG] [analyzer] Recall that we only skip NoOp casts in construction contexts. For now. We should also add support for ConstructorConversion casts as presented in the attached test case, but this requires more changes because AST around them seems different. The check was originally present but was accidentally lost during r326021. Differential Revision: https://reviews.llvm.org/D43840 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326402 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 727c304f7a..f8517cb3b1 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -1200,7 +1200,9 @@ void CFGBuilder::findConstructionContexts( } case Stmt::ImplicitCastExprClass: { auto *Cast = cast(Child); - findConstructionContexts(Layer, Cast->getSubExpr()); + // TODO: We need to support CK_ConstructorConversion, maybe other kinds? + if (Cast->getCastKind() == CK_NoOp) + findConstructionContexts(Layer, Cast->getSubExpr()); break; } case Stmt::CXXBindTemporaryExprClass: { diff --git a/test/Analysis/cfg-rich-constructors.cpp b/test/Analysis/cfg-rich-constructors.cpp index 9613fa2fbe..2ae33d3703 100644 --- a/test/Analysis/cfg-rich-constructors.cpp +++ b/test/Analysis/cfg-rich-constructors.cpp @@ -484,4 +484,35 @@ void referenceWithFunctionalCast() { void constructorInTernaryCondition() { const D &d = D(1) ? D(2) : D(3); } + } // end namespace temporary_object_expr_with_dtors + +namespace implicit_constructor_conversion { + +class A {}; +A get(); + +class B { +public: + B(const A &); + ~B() {} +}; + +// FIXME: Find construction context for the implicit constructor conversion. +// CHECK: void implicitConstructionConversionFromFunctionValue() +// CHECK: 1: get +// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conver +// CHECK-NEXT: 3: [B1.2]() +// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) +// CHECK-NEXT: 5: [B1.4] +// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, class implicit_constructor_conversion::B) +// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_convers +// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) +// CHECK-NEXT: 9: [B1.8] +// CHECK-NEXT: 10: const implicit_constructor_conversion::B &b = get(); +// CHECK-NEXT: 11: [B1.10].~B() (Implicit destructor) +void implicitConstructionConversionFromFunctionValue() { + const B &b = get(); // no-crash +} + +} // end namespace implicit_constructor_conversion