[cfe-commits] r127396 - in /cfe/trunk: include/clang/Analysis/AnalysisContext.h include/clang/Analysis/CFG.h lib/Analysis/AnalysisContext.cpp lib/Analysis/CFG.cpp lib/Sema/AnalysisBasedWarnings.cpp

Ted Kremenek kremenek at apple.com
Wed Mar 9 19:50:34 PST 2011


Author: kremenek
Date: Wed Mar  9 21:50:34 2011
New Revision: 127396

URL: http://llvm.org/viewvc/llvm-project?rev=127396&view=rev
Log:
When doing reachability analysis for warnings issued under DiagRuntimeBehavior, don't construct a ParentMap or CFGStmtMap.
Instead, create a small set of Stmt* -> CFGBlock* mappings during CFG construction for only the statements we care about
relating to the diagnostics we want to check for reachability.

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

Modified: cfe/trunk/include/clang/Analysis/AnalysisContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisContext.h?rev=127396&r1=127395&r2=127396&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Wed Mar  9 21:50:34 2011
@@ -92,6 +92,9 @@
   bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
   bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
 
+  void registerForcedBlockExpression(const Stmt *stmt);
+  const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
+  
   Stmt *getBody();
   CFG *getCFG();
   

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=127396&r1=127395&r2=127396&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Wed Mar  9 21:50:34 2011
@@ -534,7 +534,7 @@
 
   class BuildOptions {
   public:
-    typedef llvm::DenseMap<const Stmt *, const CFGBlock> ForcedBlkExprs;
+    typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
     ForcedBlkExprs **forcedBlkExprs;    
 
     bool PruneTriviallyFalseEdges:1;

Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=127396&r1=127395&r2=127396&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Wed Mar  9 21:50:34 2011
@@ -74,6 +74,26 @@
   return NULL;
 }
 
+void AnalysisContext::registerForcedBlockExpression(const Stmt *stmt) {
+  if (!forcedBlkExprs)
+    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
+  // Default construct an entry for 'stmt'.
+  if (const ParenExpr *pe = dyn_cast<ParenExpr>(stmt))
+    stmt = pe->IgnoreParens();
+  (void) (*forcedBlkExprs)[stmt];
+}
+
+const CFGBlock *
+AnalysisContext::getBlockForRegisteredExpression(const Stmt *stmt) {
+  assert(forcedBlkExprs);
+  if (const ParenExpr *pe = dyn_cast<ParenExpr>(stmt))
+    stmt = pe->IgnoreParens();
+  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr = 
+    forcedBlkExprs->find(stmt);
+  assert(itr != forcedBlkExprs->end());
+  return itr->second;
+}
+
 CFG *AnalysisContext::getCFG() {
   if (useUnoptimizedCFG)
     return getUnoptimizedCFG();

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=127396&r1=127395&r2=127396&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Wed Mar  9 21:50:34 2011
@@ -282,6 +282,8 @@
   // State to track for building switch statements.
   bool switchExclusivelyCovered;
   Expr::EvalResult *switchCond;
+  
+  CFG::BuildOptions::ForcedBlkExprs::value_type *cachedEntry;
 
 public:
   explicit CFGBuilder(ASTContext *astContext,
@@ -290,11 +292,14 @@
       Block(NULL), Succ(NULL),
       SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL),
       TryTerminatedBlock(NULL), badCFG(false), BuildOpts(buildOpts), 
-      switchExclusivelyCovered(false), switchCond(0) {}
+      switchExclusivelyCovered(false), switchCond(0),
+      cachedEntry(0) {}
 
   // buildCFG - Used by external clients to construct the CFG.
   CFG* buildCFG(const Decl *D, Stmt *Statement);
 
+  bool alwaysAdd(const Stmt *stmt);
+  
 private:
   // Visitors to walk an AST and construct the CFG.
   CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc);
@@ -387,6 +392,12 @@
 
   // Interface to CFGBlock - adding CFGElements.
   void appendStmt(CFGBlock *B, Stmt *S) {
+    if (cachedEntry) {
+      assert(cachedEntry->first == S);
+      cachedEntry->second = B;
+      cachedEntry = 0;
+    }    
+
     B->appendStmt(S, cfg->getBumpVectorContext());
   }
   void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) {
@@ -443,9 +454,26 @@
   
 };
 
-bool AddStmtChoice::alwaysAdd(CFGBuilder &builder,
-                              const Stmt *stmt) const {
-  return kind == AlwaysAdd;
+inline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder,
+                                     const Stmt *stmt) const {
+  return builder.alwaysAdd(stmt) || kind == AlwaysAdd;
+}
+  
+bool CFGBuilder::alwaysAdd(const Stmt *stmt) {
+  if (!BuildOpts.forcedBlkExprs)
+    return false;
+  
+  CFG::BuildOptions::ForcedBlkExprs *fb = *BuildOpts.forcedBlkExprs;
+
+  if (!fb)
+    return false;
+
+  CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt);
+  if (itr == fb->end())
+    return false;
+  
+  cachedEntry = &*itr;
+  return true;
 }
   
 // FIXME: Add support for dependent-sized array types in C++?

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=127396&r1=127395&r2=127396&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Wed Mar  9 21:50:34 2011
@@ -546,25 +546,41 @@
   // Emit delayed diagnostics.
   if (!fscope->PossiblyUnreachableDiags.empty()) {
     bool analyzed = false;
-    if (CFGReachabilityAnalysis *cra = AC.getCFGReachablityAnalysis())
-      if (CFGStmtMap *csm = AC.getCFGStmtMap()) {
-        analyzed = true;
-        for (llvm::SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
-             i = fscope->PossiblyUnreachableDiags.begin(),
-             e = fscope->PossiblyUnreachableDiags.end();
-             i != e; ++i) {
-          const sema::PossiblyUnreachableDiag &D = *i;
-          if (const CFGBlock *blk = csm->getBlock(D.stmt)) {
+
+    // Register the expressions with the CFGBuilder.
+    for (llvm::SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
+         i = fscope->PossiblyUnreachableDiags.begin(),
+         e = fscope->PossiblyUnreachableDiags.end();
+         i != e; ++i) {
+      if (const Stmt *stmt = i->stmt)
+        AC.registerForcedBlockExpression(stmt);
+    }
+
+    if (AC.getCFG()) {
+      analyzed = true;
+      for (llvm::SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
+            i = fscope->PossiblyUnreachableDiags.begin(),
+            e = fscope->PossiblyUnreachableDiags.end();
+            i != e; ++i)
+      {
+        const sema::PossiblyUnreachableDiag &D = *i;
+        bool processed = false;
+        if (const Stmt *stmt = i->stmt) {
+          const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt);
+          assert(block);
+          if (CFGReachabilityAnalysis *cra = AC.getCFGReachablityAnalysis()) {
             // Can this block be reached from the entrance?
-            if (cra->isReachable(&AC.getCFG()->getEntry(), blk))
+            if (cra->isReachable(&AC.getCFG()->getEntry(), block))
               S.Diag(D.Loc, D.PD);
+            processed = true;
           }
-          else {
-            // Emit the warning anyway if we cannot map to a basic block.
-            S.Diag(D.Loc, D.PD);
-          }
+        }
+        if (!processed) {
+          // Emit the warning anyway if we cannot map to a basic block.
+          S.Diag(D.Loc, D.PD);
         }
       }
+    }
 
     if (!analyzed)
       flushDiagnostics(S, fscope);





More information about the cfe-commits mailing list