r178263 - Add CFG logic to create a conditional branch for modeling static initializers.

Ted Kremenek kremenek at apple.com
Thu Mar 28 11:43:16 PDT 2013


Author: kremenek
Date: Thu Mar 28 13:43:15 2013
New Revision: 178263

URL: http://llvm.org/viewvc/llvm-project?rev=178263&view=rev
Log:
Add CFG logic to create a conditional branch for modeling static initializers.

This is an optional variant of the CFG.  This allows analyses to model whether
or not a static initializer has run, e.g.:

  static Foo x = bar();

For basic dataflow analysis in Sema we will just assume that the initializer
always runs.  For the static analyzer we can use this branch to accurately
track whether or not initializers are on.

This patch just adds the (opt-in) functionality to the CFG.  The
static analyzer still needs to be modified to adopt this feature.

Modified:
    cfe/trunk/include/clang/Analysis/CFG.h
    cfe/trunk/lib/Analysis/CFG.cpp

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=178263&r1=178262&r2=178263&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Thu Mar 28 13:43:15 2013
@@ -601,6 +601,7 @@ public:
     bool AddInitializers;
     bool AddImplicitDtors;
     bool AddTemporaryDtors;
+    bool AddStaticInitBranches;
 
     bool alwaysAdd(const Stmt *stmt) const {
       return alwaysAddMask[stmt->getStmtClass()];
@@ -621,7 +622,8 @@ public:
       ,AddEHEdges(false)
       ,AddInitializers(false)
       ,AddImplicitDtors(false)
-      ,AddTemporaryDtors(false) {}
+      ,AddTemporaryDtors(false)
+      ,AddStaticInitBranches(false) {}
   };
 
   /// \brief Provides a custom implementation of the iterator class to have the

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=178263&r1=178262&r2=178263&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Thu Mar 28 13:43:15 2013
@@ -1653,10 +1653,24 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(D
   bool IsReference = false;
   bool HasTemporaries = false;
 
+  // Guard static initializers under a branch.
+  CFGBlock *blockBeforeInit = 0;
+
   // Destructors of temporaries in initialization expression should be called
   // after initialization finishes.
   Expr *Init = VD->getInit();
   if (Init) {
+    if (BuildOpts.AddStaticInitBranches && VD->isStaticLocal()) {
+      // For static variables, we need to create a branch to track
+      // whether or not they are initialized.
+      if (Block) {
+        Succ = Block;
+        if (badCFG)
+          return 0;
+      }
+      blockBeforeInit = Succ;
+    }
+
     IsReference = VD->getType()->isReferenceType();
     HasTemporaries = isa<ExprWithCleanups>(Init);
 
@@ -1700,7 +1714,18 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(D
   if (ScopePos && VD == *ScopePos)
     ++ScopePos;
 
-  return Block ? Block : LastBlock;
+  CFGBlock *B = Block ? Block : LastBlock;
+  if (blockBeforeInit) {
+    Succ = B;
+    Block = 0;
+    CFGBlock *branchBlock = createBlock(false);
+    branchBlock->setTerminator(DS);
+    addSuccessor(branchBlock, blockBeforeInit);
+    addSuccessor(branchBlock, B);
+    B = branchBlock;
+  }
+
+  return B;
 }
 
 CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
@@ -3642,6 +3667,11 @@ public:
     Terminator->printPretty(OS, Helper, Policy);
   }
 
+  void VisitDeclStmt(DeclStmt *DS) {
+    VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
+    OS << "static init " << VD->getName();
+  }
+
   void VisitForStmt(ForStmt *F) {
     OS << "for (" ;
     if (F->getInit())





More information about the cfe-commits mailing list