[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