[PATCH] D111210: [Analysis][CFG] Fix CFG building for standalone `CaseStmt`s.
Clement Courbet via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 6 00:59:52 PDT 2021
courbet created this revision.
courbet added reviewers: Szelethus, NoQ.
courbet requested review of this revision.
Herald added a project: clang.
One is supposed ot be able to create a CFG for any statement, as per the
comment on `CFGBuilder::buildCFG`:
"The AST can represent an arbitrary statement. Examples include a single
expression or a function body (compound statement)"
When building a CFG from a `CaseStmt`, we currently have a crash:
clang/lib/Analysis/CFG.cpp:4242: clang::CFGBlock *(anonymous
namespace)::CFGBuilder::VisitCaseStmt(clang::CaseStmt *): Assertion
`SwitchTerminatedBlock' failed.
Add a unit test to show this, and avoid updating the parent `SwitchStmt`
block when none exists.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D111210
Files:
clang/lib/Analysis/CFG.cpp
clang/unittests/Analysis/CFGTest.cpp
Index: clang/unittests/Analysis/CFGTest.cpp
===================================================================
--- clang/unittests/Analysis/CFGTest.cpp
+++ clang/unittests/Analysis/CFGTest.cpp
@@ -268,6 +268,50 @@
}
}
+class CFGCallback : public ast_matchers::MatchFinder::MatchCallback {
+public:
+ CFGCallback(std::unique_ptr<ASTUnit> AST) : AST(std::move(AST)) {}
+
+ std::unique_ptr<ASTUnit> AST;
+ BuildResult TheBuildResult = BuildResult::ToolRan;
+ CFG::BuildOptions Options;
+
+ void run(const ast_matchers::MatchFinder::MatchResult &Result) override {
+ const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
+ Stmt *Body = Func->getBody();
+ if (!Body)
+ return;
+ TheBuildResult = BuildResult::SawFunctionBody;
+ Options.AddImplicitDtors = true;
+ if (std::unique_ptr<CFG> Cfg =
+ CFG::buildCFG(nullptr, Body, Result.Context, Options))
+ TheBuildResult = {BuildResult::BuiltCFG, Func, std::move(Cfg),
+ std::move(AST)};
+ }
+};
+
+// It is valid to create a CFG for a single statement. Creating a CFG for an
+// isolated `CaseStmt` should not crash.`
+TEST(CFG, SwitchCase) {
+ const char *Code = "void f(int i) {\n"
+ " switch (i) {\n"
+ " case 0:\n"
+ " return;\n"
+ " }\n"
+ "}\n";
+ std::vector<std::string> Args = {"-std=c++11",
+ "-fno-delayed-template-parsing"};
+ std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(Code, Args);
+ ASSERT_NE(AST, nullptr);
+
+ auto Matches = ast_matchers::match(ast_matchers::caseStmt().bind("case"),
+ AST->getASTContext());
+ auto *Case = ast_matchers::selectFirst<CaseStmt>("case", Matches);
+ std::unique_ptr<CFG> Cfg =
+ CFG::buildCFG(nullptr, const_cast<CaseStmt *>(Case),
+ &AST->getASTContext(), CFG::BuildOptions{});
+}
+
} // namespace
} // namespace analysis
} // namespace clang
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -4215,10 +4215,12 @@
else
TopBlock = currentBlock;
- addSuccessor(SwitchTerminatedBlock,
- shouldAddCase(switchExclusivelyCovered, switchCond,
- CS, *Context)
- ? currentBlock : nullptr);
+ if (SwitchTerminatedBlock)
+ addSuccessor(
+ SwitchTerminatedBlock,
+ shouldAddCase(switchExclusivelyCovered, switchCond, CS, *Context)
+ ? currentBlock
+ : nullptr);
LastBlock = currentBlock;
CS = cast<CaseStmt>(Sub);
@@ -4241,10 +4243,10 @@
// Add this block to the list of successors for the block with the switch
// statement.
- assert(SwitchTerminatedBlock);
- addSuccessor(SwitchTerminatedBlock, CaseBlock,
- shouldAddCase(switchExclusivelyCovered, switchCond,
- CS, *Context));
+ if (SwitchTerminatedBlock)
+ addSuccessor(
+ SwitchTerminatedBlock, CaseBlock,
+ shouldAddCase(switchExclusivelyCovered, switchCond, CS, *Context));
// We set Block to NULL to allow lazy creation of a new block (if necessary)
Block = nullptr;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111210.377455.patch
Type: text/x-patch
Size: 3391 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211006/e3256204/attachment.bin>
More information about the cfe-commits
mailing list