[PATCH] D121365: [CFG] Fix crash on CFG building when deriving from a template.
Clement Courbet via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 10 02:33:41 PST 2022
courbet created this revision.
courbet added reviewers: gribozavr, alexfh.
Herald added a project: All.
courbet requested review of this revision.
Herald added a project: clang.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D121365
Files:
clang/lib/Analysis/CFG.cpp
clang/unittests/Analysis/CFGBuildResult.h
clang/unittests/Analysis/CFGTest.cpp
Index: clang/unittests/Analysis/CFGTest.cpp
===================================================================
--- clang/unittests/Analysis/CFGTest.cpp
+++ clang/unittests/Analysis/CFGTest.cpp
@@ -70,6 +70,27 @@
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);
Index: clang/unittests/Analysis/CFGBuildResult.h
===================================================================
--- clang/unittests/Analysis/CFGBuildResult.h
+++ clang/unittests/Analysis/CFGBuildResult.h
@@ -56,13 +56,15 @@
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 @@
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);
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -1884,7 +1884,7 @@
// (which is different 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);
}
@@ -1894,7 +1894,7 @@
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);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D121365.414318.patch
Type: text/x-patch
Size: 3320 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220310/3f1512ac/attachment.bin>
More information about the cfe-commits
mailing list