forked from OSchip/llvm-project
Refactored some of the BugReporter interface so that data such as the ASTContext&, PathDiagnosticClient*, can be provided by an external source.
Split BugReporter into BugReporter and GRBugReporter so checkers not based on GRExprEngine can still use the BugReporter mechanism. llvm-svn: 53048
This commit is contained in:
parent
6d161f1fd3
commit
b1d0118a1a
|
|
@ -25,6 +25,7 @@
|
|||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/AST/ParentMap.h"
|
||||
#include "clang/Analysis/PathSensitive/BugReporter.h"
|
||||
#include "clang/Analysis/Analyses/LiveVariables.h"
|
||||
#include "clang/Analysis/LocalCheckers.h"
|
||||
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
|
||||
|
|
@ -98,7 +99,7 @@ namespace {
|
|||
};
|
||||
|
||||
|
||||
class VISIBILITY_HIDDEN AnalysisManager {
|
||||
class VISIBILITY_HIDDEN AnalysisManager : public BugReporterData {
|
||||
Decl* D;
|
||||
Stmt* Body;
|
||||
AnalysisConsumer& C;
|
||||
|
|
@ -117,25 +118,25 @@ namespace {
|
|||
Decl* getCodeDecl() const { return D; }
|
||||
Stmt* getBody() const { return Body; }
|
||||
|
||||
CFG* getCFG() {
|
||||
virtual CFG& getCFG() {
|
||||
if (!cfg) cfg.reset(CFG::buildCFG(getBody()));
|
||||
return cfg.get();
|
||||
return *cfg.get();
|
||||
}
|
||||
|
||||
ParentMap* getParentMap() {
|
||||
virtual ParentMap& getParentMap() {
|
||||
if (!PM) PM.reset(new ParentMap(getBody()));
|
||||
return PM.get();
|
||||
return *PM.get();
|
||||
}
|
||||
|
||||
ASTContext& getContext() {
|
||||
virtual ASTContext& getContext() {
|
||||
return *C.Ctx;
|
||||
}
|
||||
|
||||
SourceManager& getSourceManager() {
|
||||
virtual SourceManager& getSourceManager() {
|
||||
return getContext().getSourceManager();
|
||||
}
|
||||
|
||||
Diagnostic& getDiagnostic() {
|
||||
virtual Diagnostic& getDiagnostic() {
|
||||
return C.Diags;
|
||||
}
|
||||
|
||||
|
|
@ -143,20 +144,21 @@ namespace {
|
|||
return C.LOpts;
|
||||
}
|
||||
|
||||
PathDiagnosticClient* getPathDiagnosticClient() {
|
||||
virtual PathDiagnosticClient* getPathDiagnosticClient() {
|
||||
if (PD.get() == 0 && !C.HTMLDir.empty())
|
||||
PD.reset(CreateHTMLDiagnosticClient(C.HTMLDir, C.PP, C.PPF));
|
||||
|
||||
return PD.get();
|
||||
}
|
||||
|
||||
LiveVariables* getLiveVariables() {
|
||||
virtual LiveVariables& getLiveVariables() {
|
||||
if (!liveness) {
|
||||
liveness.reset(new LiveVariables(*getCFG()));
|
||||
liveness->runOnCFG(*getCFG());
|
||||
liveness->runOnAllBlocks(*getCFG(), 0, true);
|
||||
liveness.reset(new LiveVariables(getCFG()));
|
||||
liveness->runOnCFG(getCFG());
|
||||
liveness->runOnAllBlocks(getCFG(), 0, true);
|
||||
}
|
||||
return liveness.get();
|
||||
|
||||
return *liveness.get();
|
||||
}
|
||||
|
||||
bool shouldVisualize() const {
|
||||
|
|
@ -255,7 +257,7 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) {
|
|||
AnalysisManager mgr(*this, D, Body);
|
||||
|
||||
// Dispatch on the actions.
|
||||
for (Actions::iterator I = actions.begin(),
|
||||
for (Actions::iterator I = actions.begin(),
|
||||
E = actions.end(); I != E; ++I)
|
||||
((*I).getHead())(mgr);
|
||||
}
|
||||
|
|
@ -265,13 +267,13 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void ActionDeadStores(AnalysisManager& mgr) {
|
||||
CheckDeadStores(*mgr.getCFG(), mgr.getContext(),
|
||||
*mgr.getLiveVariables(), *mgr.getParentMap(),
|
||||
CheckDeadStores(mgr.getCFG(), mgr.getContext(),
|
||||
mgr.getLiveVariables(), mgr.getParentMap(),
|
||||
mgr.getDiagnostic());
|
||||
}
|
||||
|
||||
static void ActionUninitVals(AnalysisManager& mgr) {
|
||||
CheckUninitializedValues(*mgr.getCFG(), mgr.getContext(),
|
||||
CheckUninitializedValues(mgr.getCFG(), mgr.getContext(),
|
||||
mgr.getDiagnostic());
|
||||
}
|
||||
|
||||
|
|
@ -285,15 +287,15 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf) {
|
|||
mgr.DisplayFunction();
|
||||
|
||||
// Construct the analysis engine.
|
||||
GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(),
|
||||
*mgr.getLiveVariables());
|
||||
GRExprEngine Eng(mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(),
|
||||
mgr.getLiveVariables());
|
||||
Eng.setTransferFunctions(tf);
|
||||
|
||||
// Execute the worklist algorithm.
|
||||
Eng.ExecuteWorkList();
|
||||
|
||||
// Display warnings.
|
||||
Eng.EmitWarnings(mgr.getDiagnostic(), mgr.getPathDiagnosticClient());
|
||||
Eng.EmitWarnings(mgr);
|
||||
|
||||
// Visualize the exploded graph.
|
||||
if (mgr.shouldVisualize())
|
||||
|
|
@ -337,17 +339,17 @@ static void ActionSimpleChecks(AnalysisManager& mgr) {
|
|||
|
||||
static void ActionLiveness(AnalysisManager& mgr) {
|
||||
mgr.DisplayFunction();
|
||||
mgr.getLiveVariables()->dumpBlockLiveness(mgr.getSourceManager());
|
||||
mgr.getLiveVariables().dumpBlockLiveness(mgr.getSourceManager());
|
||||
}
|
||||
|
||||
static void ActionCFGDump(AnalysisManager& mgr) {
|
||||
mgr.DisplayFunction();
|
||||
mgr.getCFG()->dump();
|
||||
mgr.getCFG().dump();
|
||||
}
|
||||
|
||||
static void ActionCFGView(AnalysisManager& mgr) {
|
||||
mgr.DisplayFunction();
|
||||
mgr.getCFG()->viewCFG();
|
||||
mgr.getCFG().viewCFG();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
|||
|
|
@ -127,44 +127,100 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class BugReporterData {
|
||||
public:
|
||||
virtual ~BugReporterData();
|
||||
virtual Diagnostic& getDiagnostic() = 0;
|
||||
virtual PathDiagnosticClient* getPathDiagnosticClient() = 0;
|
||||
virtual ASTContext& getContext() = 0;
|
||||
virtual SourceManager& getSourceManager() = 0;
|
||||
virtual CFG& getCFG() = 0;
|
||||
virtual ParentMap& getParentMap() = 0;
|
||||
virtual LiveVariables& getLiveVariables() = 0;
|
||||
};
|
||||
|
||||
class BugReporter {
|
||||
Diagnostic& Diag;
|
||||
PathDiagnosticClient* PD;
|
||||
ASTContext& Ctx;
|
||||
GRExprEngine& Eng;
|
||||
llvm::SmallSet<SymbolID, 10> NotableSymbols;
|
||||
public:
|
||||
enum Kind { BaseBRKind, GRBugReporterKind };
|
||||
|
||||
protected:
|
||||
Kind kind;
|
||||
BugReporterData& D;
|
||||
|
||||
BugReporter(BugReporterData& d, Kind k) : kind(k), D(d) {}
|
||||
|
||||
public:
|
||||
BugReporter(Diagnostic& diag, PathDiagnosticClient* pd,
|
||||
ASTContext& ctx, GRExprEngine& eng)
|
||||
: Diag(diag), PD(pd), Ctx(ctx), Eng(eng) {}
|
||||
BugReporter(BugReporterData& d) : kind(BaseBRKind), D(d) {}
|
||||
virtual ~BugReporter();
|
||||
|
||||
~BugReporter();
|
||||
Kind getKind() const { return kind; }
|
||||
|
||||
Diagnostic& getDiagnostic() { return Diag; }
|
||||
Diagnostic& getDiagnostic() {
|
||||
return D.getDiagnostic();
|
||||
}
|
||||
|
||||
PathDiagnosticClient* getDiagnosticClient() { return PD; }
|
||||
PathDiagnosticClient* getPathDiagnosticClient() {
|
||||
return D.getPathDiagnosticClient();
|
||||
}
|
||||
|
||||
ASTContext& getContext() { return Ctx; }
|
||||
ASTContext& getContext() {
|
||||
return D.getContext();
|
||||
}
|
||||
|
||||
SourceManager& getSourceManager() { return Ctx.getSourceManager(); }
|
||||
SourceManager& getSourceManager() {
|
||||
return getContext().getSourceManager();
|
||||
}
|
||||
|
||||
ExplodedGraph<ValueState>& getGraph();
|
||||
CFG& getCFG() {
|
||||
return D.getCFG();
|
||||
}
|
||||
|
||||
ParentMap& getParentMap() {
|
||||
return D.getParentMap();
|
||||
}
|
||||
|
||||
LiveVariables& getLiveVariables() {
|
||||
return D.getLiveVariables();
|
||||
}
|
||||
|
||||
virtual void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R) {}
|
||||
|
||||
GRExprEngine& getEngine() { return Eng; }
|
||||
void EmitWarning(BugReport& R);
|
||||
|
||||
static bool classof(const BugReporter* R) { return true; }
|
||||
};
|
||||
|
||||
class GRBugReporter : public BugReporter {
|
||||
GRExprEngine& Eng;
|
||||
llvm::SmallSet<SymbolID, 10> NotableSymbols;
|
||||
public:
|
||||
|
||||
GRBugReporter(BugReporterData& d, GRExprEngine& eng)
|
||||
: BugReporter(d, GRBugReporterKind), Eng(eng) {}
|
||||
|
||||
virtual ~GRBugReporter();
|
||||
|
||||
GRExprEngine& getEngine() {
|
||||
return Eng;
|
||||
}
|
||||
|
||||
ExplodedGraph<ValueState>& getGraph();
|
||||
|
||||
ValueStateManager& getStateManager();
|
||||
|
||||
CFG& getCFG() { return getGraph().getCFG(); }
|
||||
virtual void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R);
|
||||
|
||||
void addNotableSymbol(SymbolID Sym) {
|
||||
NotableSymbols.insert(Sym);
|
||||
}
|
||||
|
||||
ParentMap& getParentMap();
|
||||
bool isNotable(SymbolID Sym) const {
|
||||
return (bool) NotableSymbols.count(Sym);
|
||||
}
|
||||
|
||||
void EmitWarning(BugReport& R);
|
||||
|
||||
void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R);
|
||||
|
||||
void addNotableSymbol(SymbolID Sym) { NotableSymbols.insert(Sym); }
|
||||
bool isNotable(SymbolID Sym) const { return (bool) NotableSymbols.count(Sym);}
|
||||
static bool classof(const BugReporter* R) {
|
||||
return R->getKind() == GRBugReporterKind;
|
||||
}
|
||||
};
|
||||
|
||||
} // end clang namespace
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace clang {
|
|||
class PathDiagnosticClient;
|
||||
class Diagnostic;
|
||||
class ParentMap;
|
||||
class BugReporterData;
|
||||
|
||||
class GRExprEngine {
|
||||
|
||||
|
|
@ -235,7 +236,7 @@ public:
|
|||
BugTypes.push_back(B);
|
||||
}
|
||||
|
||||
void EmitWarnings(Diagnostic& Diag, PathDiagnosticClient* PD);
|
||||
void EmitWarnings(BugReporterData& BRData);
|
||||
|
||||
bool isRetStackAddr(const NodeTy* N) const {
|
||||
return N->isSink() && RetsStackAddr.count(const_cast<NodeTy*>(N)) != 0;
|
||||
|
|
|
|||
|
|
@ -27,22 +27,20 @@
|
|||
using namespace clang;
|
||||
|
||||
BugReporter::~BugReporter() {}
|
||||
GRBugReporter::~GRBugReporter() {}
|
||||
BugReporterData::~BugReporterData() {}
|
||||
BugType::~BugType() {}
|
||||
BugReport::~BugReport() {}
|
||||
RangedBugReport::~RangedBugReport() {}
|
||||
|
||||
ExplodedGraph<ValueState>& BugReporter::getGraph() {
|
||||
ExplodedGraph<ValueState>& GRBugReporter::getGraph() {
|
||||
return Eng.getGraph();
|
||||
}
|
||||
|
||||
ValueStateManager& BugReporter::getStateManager() {
|
||||
ValueStateManager& GRBugReporter::getStateManager() {
|
||||
return Eng.getStateManager();
|
||||
}
|
||||
|
||||
ParentMap& BugReporter::getParentMap() {
|
||||
return Eng.getParentMap();
|
||||
}
|
||||
|
||||
static inline Stmt* GetStmt(const ProgramPoint& P) {
|
||||
if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
|
||||
return PS->getStmt();
|
||||
|
|
@ -338,7 +336,7 @@ static void HandleNotableSymbol(ExplodedNode<ValueState>* N, Stmt* S,
|
|||
// specified symbol. Are any of them not in the previous state.
|
||||
|
||||
ValueState* St = N->getState();
|
||||
ValueStateManager& VMgr = BR.getStateManager();
|
||||
ValueStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
|
||||
|
||||
// FIXME: Later generalize for a broader memory model.
|
||||
|
||||
|
|
@ -411,8 +409,8 @@ static void HandleNotableSymbol(ExplodedNode<ValueState>* N, Stmt* S,
|
|||
}
|
||||
}
|
||||
|
||||
void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||
BugReport& R) {
|
||||
void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||
BugReport& R) {
|
||||
|
||||
ExplodedNode<ValueState>* N = R.getEndNode();
|
||||
|
||||
|
|
@ -438,6 +436,7 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
ExplodedNode<ValueState>* NextNode = N->pred_empty()
|
||||
? NULL : *(N->pred_begin());
|
||||
|
||||
ASTContext& Ctx = getContext();
|
||||
SourceManager& SMgr = Ctx.getSourceManager();
|
||||
|
||||
while (NextNode) {
|
||||
|
|
@ -715,6 +714,8 @@ void BugReporter::EmitWarning(BugReport& R) {
|
|||
|
||||
// Emit a full diagnostic for the path if we have a PathDiagnosticClient.
|
||||
|
||||
PathDiagnosticClient* PD = getPathDiagnosticClient();
|
||||
|
||||
if (PD && !D->empty()) {
|
||||
PD->HandlePathDiagnostic(D.take());
|
||||
return;
|
||||
|
|
@ -723,7 +724,7 @@ void BugReporter::EmitWarning(BugReport& R) {
|
|||
// We don't have a PathDiagnosticClient, but we can still emit a single
|
||||
// line diagnostic. Determine the location.
|
||||
|
||||
FullSourceLoc L = D->empty() ? R.getLocation(Ctx.getSourceManager())
|
||||
FullSourceLoc L = D->empty() ? R.getLocation(getSourceManager())
|
||||
: D->back()->getLocation();
|
||||
|
||||
|
||||
|
|
@ -749,7 +750,6 @@ void BugReporter::EmitWarning(BugReport& R) {
|
|||
}
|
||||
else {
|
||||
std::ostringstream os;
|
||||
os << "[CHECKER] ";
|
||||
|
||||
if (D->empty())
|
||||
os << R.getDescription();
|
||||
|
|
@ -757,6 +757,7 @@ void BugReporter::EmitWarning(BugReport& R) {
|
|||
os << D->back()->getString();
|
||||
|
||||
|
||||
Diagnostic& Diag = getDiagnostic();
|
||||
unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning,
|
||||
os.str().c_str());
|
||||
|
||||
|
|
|
|||
|
|
@ -2202,7 +2202,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(ExplodedNode<ValueState>* N,
|
|||
// Add the range by scanning the children of the statement for any bindings
|
||||
// to Sym.
|
||||
|
||||
ValueStateManager& VSM = BR.getEngine().getStateManager();
|
||||
ValueStateManager& VSM = cast<GRBugReporter>(BR).getStateManager();
|
||||
|
||||
for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
|
||||
if (Expr* Exp = dyn_cast_or_null<Expr>(*I)) {
|
||||
|
|
@ -2266,7 +2266,7 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
|
|||
|
||||
// Tell the BugReporter to report cases when the tracked symbol is
|
||||
// assigned to different variables, etc.
|
||||
BR.addNotableSymbol(Sym);
|
||||
cast<GRBugReporter>(BR).addNotableSymbol(Sym);
|
||||
|
||||
if (!getBugType().isLeak())
|
||||
return RangedBugReport::getEndPath(BR, EndN);
|
||||
|
|
|
|||
|
|
@ -242,8 +242,8 @@ public:
|
|||
DiagCollector C(*this);
|
||||
DeadStoreObs A(BR.getContext(), BR.getDiagnostic(), C, BR.getParentMap());
|
||||
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
Eng.getLiveness().runOnAllBlocks(BR.getCFG(), &A);
|
||||
|
||||
BR.getLiveVariables().runOnAllBlocks(BR.getCFG(), &A);
|
||||
|
||||
// Emit the bug reports.
|
||||
|
||||
|
|
|
|||
|
|
@ -108,21 +108,21 @@ struct VISIBILITY_HIDDEN SaveOr {
|
|||
};
|
||||
|
||||
|
||||
void GRExprEngine::EmitWarnings(Diagnostic& Diag, PathDiagnosticClient* PD) {
|
||||
void GRExprEngine::EmitWarnings(BugReporterData& BRData) {
|
||||
for (bug_type_iterator I = bug_types_begin(), E = bug_types_end(); I!=E; ++I){
|
||||
BugReporter BR(Diag, PD, getContext(), *this);
|
||||
GRBugReporter BR(BRData, *this);
|
||||
(*I)->EmitWarnings(BR);
|
||||
}
|
||||
|
||||
for (SimpleChecksTy::iterator I = CallChecks.begin(), E = CallChecks.end();
|
||||
I != E; ++I) {
|
||||
BugReporter BR(Diag, PD, getContext(), *this);
|
||||
GRBugReporter BR(BRData, *this);
|
||||
(*I)->EmitWarnings(BR);
|
||||
}
|
||||
|
||||
for (SimpleChecksTy::iterator I=MsgExprChecks.begin(), E=MsgExprChecks.end();
|
||||
I != E; ++I) {
|
||||
BugReporter BR(Diag, PD, getContext(), *this);
|
||||
GRBugReporter BR(BRData, *this);
|
||||
(*I)->EmitWarnings(BR);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
GenericEmitWarnings(BR, *this, Eng.null_derefs_begin(),
|
||||
Eng.null_derefs_end());
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
GenericEmitWarnings(BR, *this, Eng.undef_derefs_begin(),
|
||||
Eng.undef_derefs_end());
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
GenericEmitWarnings(BR, *this, Eng.explicit_bad_divides_begin(),
|
||||
Eng.explicit_bad_divides_end());
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
GenericEmitWarnings(BR, *this, Eng.undef_results_begin(),
|
||||
Eng.undef_results_end());
|
||||
}
|
||||
|
|
@ -147,7 +147,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
GenericEmitWarnings(BR, *this, Eng.bad_calls_begin(),
|
||||
Eng.bad_calls_end());
|
||||
}
|
||||
|
|
@ -168,7 +168,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
|
||||
for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
|
||||
E = Eng.undef_arg_end(); I!=E; ++I) {
|
||||
|
|
@ -195,7 +195,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
|
||||
for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
|
||||
E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
|
||||
|
|
@ -221,7 +221,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
|
||||
for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
|
||||
End = Eng.undef_receivers_end(); I!=End; ++I) {
|
||||
|
|
@ -252,7 +252,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void EmitWarnings(BugReporter& BR) {
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
GenericEmitWarnings(BR, *this, Eng.ret_stackaddr_begin(),
|
||||
Eng.ret_stackaddr_end());
|
||||
}
|
||||
|
|
@ -291,7 +291,7 @@ struct VISIBILITY_HIDDEN FindUndefExpr {
|
|||
|
||||
void UndefBranch::EmitWarnings(BugReporter& BR) {
|
||||
|
||||
GRExprEngine& Eng = BR.getEngine();
|
||||
GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
|
||||
|
||||
for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
|
||||
E=Eng.undef_branches_end(); I!=E; ++I) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue