r326402 - [CFG] [analyzer] Recall that we only skip NoOp casts in construction contexts.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 28 17:09:24 PST 2018


Author: dergachev
Date: Wed Feb 28 17:09:24 2018
New Revision: 326402

URL: http://llvm.org/viewvc/llvm-project?rev=326402&view=rev
Log:
[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

Modified:
    cfe/trunk/lib/Analysis/CFG.cpp
    cfe/trunk/test/Analysis/cfg-rich-constructors.cpp

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=326402&r1=326401&r2=326402&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Wed Feb 28 17:09:24 2018
@@ -1200,7 +1200,9 @@ void CFGBuilder::findConstructionContext
   }
   case Stmt::ImplicitCastExprClass: {
     auto *Cast = cast<ImplicitCastExpr>(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: {

Modified: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cfg-rich-constructors.cpp?rev=326402&r1=326401&r2=326402&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp (original)
+++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp Wed Feb 28 17:09:24 2018
@@ -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




More information about the cfe-commits mailing list