[clang] 3682e22 - [clang][dataflow] Improve handling of constructor initializers.

Yitzhak Mandelbaum via cfe-commits cfe-commits at lists.llvm.org
Fri May 27 07:02:15 PDT 2022


Author: Yitzhak Mandelbaum
Date: 2022-05-27T13:54:11Z
New Revision: 3682e22ef404e1314ee1eab9daf6de99dc9ea8ee

URL: https://github.com/llvm/llvm-project/commit/3682e22ef404e1314ee1eab9daf6de99dc9ea8ee
DIFF: https://github.com/llvm/llvm-project/commit/3682e22ef404e1314ee1eab9daf6de99dc9ea8ee.diff

LOG: [clang][dataflow] Improve handling of constructor initializers.

Currently, we assert that `CXXCtorInitializer`s are field initializers. Replace
the assertion with an early return. Otherwise, we crash every time we process a
constructor with a non-field (e.g. base class) initializer.

Differential Revision: https://reviews.llvm.org/D126419

Added: 
    

Modified: 
    clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
    clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index ee1723dcd8cc..8a5d5ca386af 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -257,6 +257,11 @@ static void transferCFGInitializer(const CFGInitializer &CfgInit,
   const CXXCtorInitializer *Initializer = CfgInit.getInitializer();
   assert(Initializer != nullptr);
 
+  const FieldDecl *Member = Initializer->getMember();
+  if (Member == nullptr)
+    // Not a field initializer.
+    return;
+
   auto *InitStmt = Initializer->getInit();
   assert(InitStmt != nullptr);
 
@@ -269,9 +274,6 @@ static void transferCFGInitializer(const CFGInitializer &CfgInit,
   if (InitStmtVal == nullptr)
     return;
 
-  const FieldDecl *Member = Initializer->getMember();
-  assert(Member != nullptr);
-
   if (Member->getType()->isReferenceType()) {
     auto &MemberLoc = ThisLoc.getChild(*Member);
     State.Env.setValue(MemberLoc,

diff  --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index dbf59bf69556..efea7797b45f 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1296,6 +1296,49 @@ TEST_F(TransferTest, ClassMember) {
       });
 }
 
+TEST_F(TransferTest, BaseClassInitializer) {
+  using ast_matchers::cxxConstructorDecl;
+  using ast_matchers::hasName;
+  using ast_matchers::ofClass;
+
+  std::string Code = R"(
+    class A {
+    public:
+      A(int I) : Bar(I) {}
+      int Bar;
+    };
+
+    class B : public A {
+    public:
+      B(int I) : A(I) {
+        (void)0;
+        // [[p]]
+      }
+    };
+  )";
+  ASSERT_THAT_ERROR(
+      test::checkDataflow<NoopAnalysis>(
+          Code, cxxConstructorDecl(ofClass(hasName("B"))),
+          [](ASTContext &C, Environment &) {
+            return NoopAnalysis(C, /*ApplyBuiltinTransfer=*/true);
+          },
+          [](llvm::ArrayRef<
+                 std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
+                 Results,
+             ASTContext &ASTCtx) {
+            // Regression test to verify that base-class initializers do not
+            // trigger an assertion. If we add support for such initializers in
+            // the future, we can expand this test to check more specific
+            // properties.
+            EXPECT_THAT(Results, ElementsAre(Pair("p", _)));
+          },
+          {"-fsyntax-only", "-fno-delayed-template-parsing",
+           "-std=" + std::string(LangStandard::getLangStandardForKind(
+                                     LangStandard::lang_cxx17)
+                                     .getName())}),
+      llvm::Succeeded());
+}
+
 TEST_F(TransferTest, ReferenceMember) {
   std::string Code = R"(
     struct A {


        


More information about the cfe-commits mailing list