aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-07-19 14:18:43 +0000
committerTed Kremenek <kremenek@apple.com>2011-07-19 14:18:43 +0000
commit74fb1a493cf5d2dd0fb51a4eadf74e85e10a3457 (patch)
treef690eaccfe32995ffd469550dd3147da723d3c4d
parent22de49cbed981aec160556761113b667598c2a63 (diff)
Add hooks into the CFG builder to force that specific expressions are always CFGElements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135479 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Analysis/AnalysisContext.h9
-rw-r--r--include/clang/Analysis/CFG.h20
-rw-r--r--lib/Analysis/CFG.cpp12
3 files changed, 32 insertions, 9 deletions
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 6a1876e659..421dbb0dff 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -81,6 +81,15 @@ public:
idx::TranslationUnit *getTranslationUnit() const { return TU; }
+ /// Return the build options used to construct the CFG.
+ CFG::BuildOptions &getCFGBuildOptions() {
+ return cfgBuildOptions;
+ }
+
+ const CFG::BuildOptions &getCFGBuildOptions() const {
+ return cfgBuildOptions;
+ }
+
/// getAddEHEdges - Return true iff we are adding exceptional edges from
/// callExprs. If this is false, then try/catch statements and blocks
/// reachable from them can appear to be dead in the CFG, analysis passes must
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index ca46459afd..83f5b1549e 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -21,6 +21,8 @@
#include "llvm/Support/Casting.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/BitVector.h"
+#include "clang/AST/Stmt.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/Basic/SourceLocation.h"
#include <cassert>
@@ -533,6 +535,7 @@ public:
//===--------------------------------------------------------------------===//
class BuildOptions {
+ llvm::BitVector alwaysAddMask;
public:
typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
ForcedBlkExprs **forcedBlkExprs;
@@ -541,12 +544,21 @@ public:
bool AddEHEdges:1;
bool AddInitializers:1;
bool AddImplicitDtors:1;
+
+ bool alwaysAdd(const Stmt *stmt) const {
+ return alwaysAddMask[stmt->getStmtClass()];
+ }
+
+ void setAlwaysAdd(Stmt::StmtClass stmtClass) {
+ alwaysAddMask[stmtClass] = true;
+ }
BuildOptions()
- : forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
- , AddEHEdges(false)
- , AddInitializers(false)
- , AddImplicitDtors(false) {}
+ : alwaysAddMask(Stmt::lastStmtConstant, false)
+ ,forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
+ ,AddEHEdges(false)
+ ,AddInitializers(false)
+ ,AddImplicitDtors(false) {}
};
/// buildCFG - Builds a CFG from an AST. The responsibility to free the
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index f231c147f1..2a13450b4d 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -394,7 +394,7 @@ private:
// Interface to CFGBlock - adding CFGElements.
void appendStmt(CFGBlock *B, const Stmt *S) {
- if (alwaysAdd(S))
+ if (alwaysAdd(S) && cachedEntry)
cachedEntry->second = B;
// All block-level expressions should have already been IgnoreParens()ed.
@@ -461,15 +461,17 @@ inline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder,
}
bool CFGBuilder::alwaysAdd(const Stmt *stmt) {
+ bool shouldAdd = BuildOpts.alwaysAdd(stmt);
+
if (!BuildOpts.forcedBlkExprs)
- return false;
+ return shouldAdd;
if (lastLookup == stmt) {
if (cachedEntry) {
assert(cachedEntry->first == stmt);
return true;
}
- return false;
+ return shouldAdd;
}
lastLookup = stmt;
@@ -480,13 +482,13 @@ bool CFGBuilder::alwaysAdd(const Stmt *stmt) {
if (!fb) {
// No need to update 'cachedEntry', since it will always be null.
assert(cachedEntry == 0);
- return false;
+ return shouldAdd;
}
CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt);
if (itr == fb->end()) {
cachedEntry = 0;
- return false;
+ return shouldAdd;
}
cachedEntry = &*itr;