[clang] 672311b - [CFG] Fix crash on CFG building when deriving from a template.

Clement Courbet via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 16 04:01:30 PDT 2022


Author: Clement Courbet
Date: 2022-08-16T13:01:13+02:00
New Revision: 672311bd77c594888e2660c124d7eae01822fffa

URL: https://github.com/llvm/llvm-project/commit/672311bd77c594888e2660c124d7eae01822fffa
DIFF: https://github.com/llvm/llvm-project/commit/672311bd77c594888e2660c124d7eae01822fffa.diff

LOG: [CFG] Fix crash on CFG building when deriving from a template.

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

Added: 
    

Modified: 
    clang/lib/Analysis/CFG.cpp
    clang/unittests/Analysis/CFGBuildResult.h
    clang/unittests/Analysis/CFGTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 5c45264896027..2b99b8e680805 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -1891,7 +1891,7 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
     // (which is 
diff erent from the current class) is responsible for
     // destroying them.
     const CXXRecordDecl *CD = VI.getType()->getAsCXXRecordDecl();
-    if (!CD->hasTrivialDestructor()) {
+    if (CD && !CD->hasTrivialDestructor()) {
       autoCreateBlock();
       appendBaseDtor(Block, &VI);
     }
@@ -1901,7 +1901,7 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
   for (const auto &BI : RD->bases()) {
     if (!BI.isVirtual()) {
       const CXXRecordDecl *CD = BI.getType()->getAsCXXRecordDecl();
-      if (!CD->hasTrivialDestructor()) {
+      if (CD && !CD->hasTrivialDestructor()) {
         autoCreateBlock();
         appendBaseDtor(Block, &BI);
       }

diff  --git a/clang/unittests/Analysis/CFGBuildResult.h b/clang/unittests/Analysis/CFGBuildResult.h
index 4851d3d7fb6d6..72ad1cc7ce401 100644
--- a/clang/unittests/Analysis/CFGBuildResult.h
+++ b/clang/unittests/Analysis/CFGBuildResult.h
@@ -56,13 +56,15 @@ class CFGCallback : public ast_matchers::MatchFinder::MatchCallback {
     TheBuildResult = BuildResult::SawFunctionBody;
     Options.AddImplicitDtors = true;
     if (std::unique_ptr<CFG> Cfg =
-            CFG::buildCFG(nullptr, Body, Result.Context, Options))
+            CFG::buildCFG(Func, Body, Result.Context, Options))
       TheBuildResult = {BuildResult::BuiltCFG, Func, std::move(Cfg),
                         std::move(AST)};
   }
 };
 
-inline BuildResult BuildCFG(const char *Code, CFG::BuildOptions Options = {}) {
+template <typename FuncMatcherT = ast_matchers::internal::TrueMatcher>
+BuildResult BuildCFG(const char *Code, CFG::BuildOptions Options = {},
+                     FuncMatcherT FuncMatcher = ast_matchers::anything()) {
   std::vector<std::string> Args = {"-std=c++11",
                                    "-fno-delayed-template-parsing"};
   std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(Code, Args);
@@ -72,7 +74,8 @@ inline BuildResult BuildCFG(const char *Code, CFG::BuildOptions Options = {}) {
   CFGCallback Callback(std::move(AST));
   Callback.Options = Options;
   ast_matchers::MatchFinder Finder;
-  Finder.addMatcher(ast_matchers::functionDecl().bind("func"), &Callback);
+  Finder.addMatcher(ast_matchers::functionDecl(FuncMatcher).bind("func"),
+                    &Callback);
 
   Finder.matchAST(Callback.AST->getASTContext());
   return std::move(Callback.TheBuildResult);

diff  --git a/clang/unittests/Analysis/CFGTest.cpp b/clang/unittests/Analysis/CFGTest.cpp
index 1cce8bade42fe..7ce35e3fe4a4f 100644
--- a/clang/unittests/Analysis/CFGTest.cpp
+++ b/clang/unittests/Analysis/CFGTest.cpp
@@ -70,6 +70,27 @@ TEST(CFG, VariableOfIncompleteType) {
   EXPECT_EQ(BuildResult::BuiltCFG, BuildCFG(Code).getStatus());
 }
 
+// Constructing a CFG with a dependent base should not crash.
+TEST(CFG, DependantBaseAddImplicitDtors) {
+  const char *Code = R"(
+    template <class T>
+    struct Base {
+      virtual ~Base() {}
+    };
+
+    template <typename T>
+    struct Derived : public Base<T> {
+      virtual ~Derived() {}
+    };
+  )";
+  CFG::BuildOptions Options;
+  Options.AddImplicitDtors = true;
+  Options.setAllAlwaysAdd();
+  EXPECT_EQ(BuildResult::BuiltCFG,
+            BuildCFG(Code, Options, ast_matchers::hasName("~Derived<T>"))
+                .getStatus());
+}
+
 TEST(CFG, IsLinear) {
   auto expectLinear = [](bool IsLinear, const char *Code) {
     BuildResult B = BuildCFG(Code);


        


More information about the cfe-commits mailing list