[cfe-commits] r61106 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRCoreEngine.h include/clang/Analysis/PathSensitive/GRWorkList.h lib/Analysis/GRCoreEngine.cpp
Ted Kremenek
kremenek at apple.com
Tue Dec 16 14:13:34 PST 2008
Author: kremenek
Date: Tue Dec 16 16:13:33 2008
New Revision: 61106
URL: http://llvm.org/viewvc/llvm-project?rev=61106&view=rev
Log:
Add new GRWorkList class that uses two queues:
- one queue (FIFO) to queue up nodes at block entrances
- another queue (LIFO) to queue up other nodes
- The idea is to explore basic blocks to completion, but to do a BFS exploration of blocks.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h
cfe/trunk/lib/Analysis/GRCoreEngine.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h?rev=61106&r1=61105&r2=61106&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h Tue Dec 16 16:13:33 2008
@@ -613,7 +613,8 @@
/// Construct a GRCoreEngine object to analyze the provided CFG using
/// a DFS exploration of the exploded graph.
GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, SubEngineTy& subengine)
- : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx), GRWorkList::MakeDFS()),
+ : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx),
+ GRWorkList::MakeBFSBlockDFSContents()),
SubEngine(subengine) {}
/// Construct a GRCoreEngine object to analyze the provided CFG and to
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h?rev=61106&r1=61105&r2=61106&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h Tue Dec 16 16:13:33 2008
@@ -69,6 +69,7 @@
GRBlockCounter getBlockCounter() const { return CurrentCounter; }
static GRWorkList* MakeDFS();
+ static GRWorkList* MakeBFSBlockDFSContents();
};
} // end clang namespace
#endif
Modified: cfe/trunk/lib/Analysis/GRCoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRCoreEngine.cpp?rev=61106&r1=61105&r2=61106&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRCoreEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRCoreEngine.cpp Tue Dec 16 16:13:33 2008
@@ -18,11 +18,16 @@
#include "llvm/Support/Casting.h"
#include "llvm/ADT/DenseMap.h"
#include <vector>
+#include <queue>
using llvm::cast;
using llvm::isa;
using namespace clang;
+//===----------------------------------------------------------------------===//
+// Worklist classes for exploration of reachable states.
+//===----------------------------------------------------------------------===//
+
namespace {
class VISIBILITY_HIDDEN DFS : public GRWorkList {
llvm::SmallVector<GRWorkListUnit,20> Stack;
@@ -50,6 +55,48 @@
GRWorkList* GRWorkList::MakeDFS() { return new DFS(); }
+namespace {
+ class VISIBILITY_HIDDEN BFSBlockDFSContents : public GRWorkList {
+ std::queue<GRWorkListUnit> Queue;
+ llvm::SmallVector<GRWorkListUnit,20> Stack;
+ public:
+ virtual bool hasWork() const {
+ return !Queue.empty() || !Stack.empty();
+ }
+
+ virtual void Enqueue(const GRWorkListUnit& U) {
+ if (isa<BlockEntrance>(U.getNode()->getLocation()))
+ Queue.push(U);
+ else
+ Stack.push_back(U);
+ }
+
+ virtual GRWorkListUnit Dequeue() {
+ // Process all basic blocks to completion.
+ if (!Stack.empty()) {
+ const GRWorkListUnit& U = Stack.back();
+ Stack.pop_back(); // This technically "invalidates" U, but we are fine.
+ return U;
+ }
+
+ assert(!Queue.empty());
+ // Don't use const reference. The subsequent pop_back() might make it
+ // unsafe.
+ GRWorkListUnit U = Queue.front();
+ Queue.pop();
+ return U;
+ }
+ };
+} // end anonymous namespace
+
+GRWorkList* GRWorkList::MakeBFSBlockDFSContents() {
+ return new BFSBlockDFSContents();
+}
+
+//===----------------------------------------------------------------------===//
+// Core analysis engine.
+//===----------------------------------------------------------------------===//
+
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
bool GRCoreEngineImpl::ExecuteWorkList(unsigned Steps) {
@@ -90,8 +137,7 @@
// Dispatch on the location type.
switch (Node->getLocation().getKind()) {
- default:
- assert (isa<BlockEdge>(Node->getLocation()));
+ case ProgramPoint::BlockEdgeKind:
HandleBlockEdge(cast<BlockEdge>(Node->getLocation()), Node);
break;
@@ -102,9 +148,9 @@
case ProgramPoint::BlockExitKind:
assert (false && "BlockExit location never occur in forward analysis.");
break;
-
- case ProgramPoint::PostLoadKind:
- case ProgramPoint::PostStmtKind:
+
+ default:
+ assert(isa<PostStmt>(Node->getLocation()));
HandlePostStmt(cast<PostStmt>(Node->getLocation()), WU.getBlock(),
WU.getIndex(), Node);
break;
@@ -332,6 +378,18 @@
case ProgramPoint::PostLoadKind:
return PostLoad(S);
+
+ case ProgramPoint::PostUndefLocationCheckFailedKind:
+ return PostUndefLocationCheckFailed(S);
+
+ case ProgramPoint::PostLocationChecksSucceedKind:
+ return PostLocationChecksSucceed(S);
+
+ case ProgramPoint::PostOutOfBoundsCheckFailedKind:
+ return PostOutOfBoundsCheckFailed(S);
+
+ case ProgramPoint::PostNullCheckFailedKind:
+ return PostNullCheckFailed(S);
case ProgramPoint::PostStoreKind:
return PostStore(S);
More information about the cfe-commits
mailing list