[PATCH] D71791: [CFG] Fix an assertion failure with static initializers

Gábor Horváth via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 23 10:01:46 PST 2019


xazax.hun updated this revision to Diff 235161.
xazax.hun added a comment.

I decided to fix the unittests. Having CFGs full of dangling pointers to the AST does not look fun at all, so I think this change was long overdue.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71791/new/

https://reviews.llvm.org/D71791

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
@@ -30,6 +30,22 @@
   EXPECT_EQ(BuildResult::SawFunctionBody, BuildCFG(Code).getStatus());
 }
 
+TEST(CFG, StaticInitializerLastCondition) {
+  const char *Code = "void f() {\n"
+                     "  int i = 5 ;\n"
+                     "  static int j = 3 ;\n"
+                     "}\n";
+  CFG::BuildOptions Options;
+  Options.AddStaticInitBranches = true;
+  Options.setAllAlwaysAdd();
+  BuildResult B = BuildCFG(Code, Options);
+  EXPECT_EQ(BuildResult::BuiltCFG, B.getStatus());
+  EXPECT_EQ(1, B.getCFG()->getEntry().succ_size());
+  CFGBlock *Block = *B.getCFG()->getEntry().succ_begin();
+  EXPECT_TRUE(isa<DeclStmt>(Block->getTerminatorStmt()));
+  EXPECT_EQ(nullptr, Block->getLastCondition());
+}
+
 // Constructing a CFG containing a delete expression on a dependent type should
 // not crash.
 TEST(CFG, DeleteExpressionOnDependentType) {
Index: clang/unittests/Analysis/CFGBuildResult.h
===================================================================
--- clang/unittests/Analysis/CFGBuildResult.h
+++ clang/unittests/Analysis/CFGBuildResult.h
@@ -27,15 +27,19 @@
 
   Status getStatus() const { return S; }
   CFG *getCFG() const { return Cfg.get(); }
+  ASTUnit *getAST() const { return AST.get(); }
+  void setAST(std::unique_ptr<ASTUnit> AST) { this->AST = std::move(AST); }
 
 private:
   Status S;
   std::unique_ptr<CFG> Cfg;
+  std::unique_ptr<ASTUnit> AST;
 };
 
 class CFGCallback : public ast_matchers::MatchFinder::MatchCallback {
 public:
   BuildResult TheBuildResult = BuildResult::ToolRan;
+  CFG::BuildOptions Options;
 
   void run(const ast_matchers::MatchFinder::MatchResult &Result) override {
     const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
@@ -43,7 +47,6 @@
     if (!Body)
       return;
     TheBuildResult = BuildResult::SawFunctionBody;
-    CFG::BuildOptions Options;
     Options.AddImplicitDtors = true;
     if (std::unique_ptr<CFG> Cfg =
             CFG::buildCFG(nullptr, Body, Result.Context, Options))
@@ -51,17 +54,19 @@
   }
 };
 
-inline BuildResult BuildCFG(const char *Code) {
+inline BuildResult BuildCFG(const char *Code, CFG::BuildOptions Options = {}) {
   CFGCallback Callback;
+  Callback.Options = Options;
 
   ast_matchers::MatchFinder Finder;
   Finder.addMatcher(ast_matchers::functionDecl().bind("func"), &Callback);
-  std::unique_ptr<tooling::FrontendActionFactory> Factory(
-      tooling::newFrontendActionFactory(&Finder));
   std::vector<std::string> Args = {"-std=c++11",
                                    "-fno-delayed-template-parsing"};
-  if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args))
+  std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(Code, Args);
+  if (!AST)
     return BuildResult::ToolFailed;
+  Finder.matchAST(AST->getASTContext());
+  Callback.TheBuildResult.setAST(std::move(AST));
   return std::move(Callback.TheBuildResult);
 }
 
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -5919,7 +5919,7 @@
     return nullptr;
 
   const Stmt *Cond = StmtElem->getStmt();
-  if (isa<ObjCForCollectionStmt>(Cond))
+  if (isa<ObjCForCollectionStmt>(Cond) || isa<DeclStmt>(Cond))
     return nullptr;
 
   // Only ObjCForCollectionStmt is known not to be a non-Expr terminator, hence


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D71791.235161.patch
Type: text/x-patch
Size: 3549 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191223/16c1c69a/attachment.bin>


More information about the cfe-commits mailing list