"llvm/lib/Target/git@repo.hca.bsc.es:rferrer/llvm-epi-0.8.git" did not exist on "399add01d423800b4cf664f23b52d53dadd36fd5"
Newer
Older
//=-- GRExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a meta-engine for path-sensitive dataflow analysis that
// is built on GREngine, but provides the boilerplate to execute transfer
// functions and build the ExplodedGraph at the expression level.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
Ted Kremenek
committed
#include "clang/Basic/SourceManager.h"
Ted Kremenek
committed
#include "llvm/ADT/ImmutableList.h"
#include "llvm/Support/Compiler.h"
Ted Kremenek
committed
#ifndef NDEBUG
#include "llvm/Support/GraphWriter.h"
#include <sstream>
#endif
using namespace clang;
using llvm::dyn_cast;
using llvm::cast;
using llvm::APSInt;
Ted Kremenek
committed
//===----------------------------------------------------------------------===//
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
Ted Kremenek
committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
namespace {
class VISIBILITY_HIDDEN MappedBatchAuditor : public GRSimpleAPICheck {
typedef llvm::ImmutableList<GRSimpleAPICheck*> Checks;
typedef llvm::DenseMap<void*,Checks> MapTy;
MapTy M;
Checks::Factory F;
public:
MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) : F(Alloc) {}
virtual ~MappedBatchAuditor() {
llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited;
for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){
GRSimpleAPICheck* check = *I;
if (AlreadyVisited.count(check))
continue;
AlreadyVisited.insert(check);
delete check;
}
}
void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
assert (A && "Check cannot be null.");
void* key = reinterpret_cast<void*>((uintptr_t) C);
MapTy::iterator I = M.find(key);
M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second);
}
virtual void EmitWarnings(BugReporter& BR) {
llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited;
for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){
GRSimpleAPICheck* check = *I;
if (AlreadyVisited.count(check))
continue;
check->EmitWarnings(BR);
}
}
virtual bool Audit(NodeTy* N, GRStateManager& VMgr) {
Ted Kremenek
committed
Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
void* key = reinterpret_cast<void*>((uintptr_t) S->getStmtClass());
MapTy::iterator MI = M.find(key);
if (MI == M.end())
return false;
bool isSink = false;
for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I)
Ted Kremenek
committed
isSink |= (*I)->Audit(N, VMgr);
Ted Kremenek
committed
return isSink;
}
};
} // end anonymous namespace
//===----------------------------------------------------------------------===//
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
Ted Kremenek
committed
static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(0, &II);
}
Ted Kremenek
committed
GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
Zhongxing Xu
committed
LiveVariables& L, bool purgeDead,
StoreManagerCreator SMC,
ConstraintManagerCreator CMC)
: CoreEngine(cfg, CD, Ctx, *this),
G(CoreEngine.getGraph()),
Ted Kremenek
committed
Liveness(L),
Builder(NULL),
StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
SymMgr(StateMgr.getSymbolManager()),
Ted Kremenek
committed
CurrentStmt(NULL),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
RaiseSel(GetNullarySelector("raise", G.getContext())),
PurgeDead(purgeDead){}
for (BugTypeSet::iterator I = BugTypes.begin(), E = BugTypes.end(); I!=E; ++I)
delete *I;
Ted Kremenek
committed
Ted Kremenek
committed
delete [] NSExceptionInstanceRaiseSelectors;
}
//===----------------------------------------------------------------------===//
// Utility methods.
//===----------------------------------------------------------------------===//
// SaveAndRestore - A utility class that uses RIIA to save and restore
// the value of a variable.
template<typename T>
struct VISIBILITY_HIDDEN SaveAndRestore {
SaveAndRestore(T& x) : X(x), old_value(x) {}
~SaveAndRestore() { X = old_value; }
T get() { return old_value; }
T& X;
T old_value;
};
// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
// value of a variable is saved, and during the dstor the old value is
// or'ed with the new value.
struct VISIBILITY_HIDDEN SaveOr {
SaveOr(bool& x) : X(x), old_value(x) { x = false; }
~SaveOr() { X |= old_value; }
bool& X;
bool old_value;
};
void GRExprEngine::EmitWarnings(BugReporterData& BRData) {
for (bug_type_iterator I = bug_types_begin(), E = bug_types_end(); I!=E; ++I){
GRBugReporter BR(BRData, *this);
(*I)->EmitWarnings(BR);
}
Ted Kremenek
committed
if (BatchAuditor) {
GRBugReporter BR(BRData, *this);
Ted Kremenek
committed
BatchAuditor->EmitWarnings(BR);
}
}
void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
Ted Kremenek
committed
StateMgr.TF = tf;
tf->RegisterChecks(*this);
tf->RegisterPrinters(getStateManager().Printers);
}
Ted Kremenek
committed
void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
if (!BatchAuditor)
BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C);
}
const GRState* GRExprEngine::getInitialState() {
//===----------------------------------------------------------------------===//
// Top-level transfer function logic (Dispatcher).
//===----------------------------------------------------------------------===//
Loading
Loading full blame...