[cfe-commits] r49180 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BugReporter.h include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h lib/Analysis/BasicObjCFoundationChecks.cpp lib/Analysis/BugReporter.cpp lib/Analysis/GRSimpleVals.cpp lib/Analysis/GRSimpleVals.h
Ted Kremenek
kremenek at apple.com
Thu Apr 3 10:57:39 PDT 2008
Author: kremenek
Date: Thu Apr 3 12:57:38 2008
New Revision: 49180
URL: http://llvm.org/viewvc/llvm-project?rev=49180&view=rev
Log:
Hooked up GRSimpleAPICheck and the simple Objective-C Foundation checks to use
the new BugReporter interface.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp
cfe/trunk/lib/Analysis/BugReporter.cpp
cfe/trunk/lib/Analysis/GRSimpleVals.cpp
cfe/trunk/lib/Analysis/GRSimpleVals.h
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h?rev=49180&r1=49179&r2=49180&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Thu Apr 3 12:57:38 2008
@@ -41,6 +41,9 @@
virtual PathDiagnosticPiece* getEndPath(ASTContext& Ctx,
ExplodedNode<ValueState> *N) const;
+
+ virtual void getRanges(const SourceRange*& beg,
+ const SourceRange*& end) const;
};
class BugReporter {
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h?rev=49180&r1=49179&r2=49180&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h Thu Apr 3 12:57:38 2008
@@ -22,12 +22,20 @@
class ValueState;
class Diagnostic;
+class BugReporter;
+class ASTContext;
+class GRExprEngine;
+class PathDiagnosticClient;
+template <typename T> class ExplodedGraph;
+
class GRSimpleAPICheck : public GRAuditor<ValueState> {
public:
GRSimpleAPICheck() {}
virtual ~GRSimpleAPICheck() {}
- virtual void ReportResults(Diagnostic& D) {}
+ virtual void ReportResults(Diagnostic& Diag, PathDiagnosticClient* PD,
+ ASTContext& Ctx, BugReporter& BR,
+ ExplodedGraph<GRExprEngine>& G) = 0;
};
} // end namespace clang
Modified: cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp?rev=49180&r1=49179&r2=49180&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp Thu Apr 3 12:57:38 2008
@@ -16,9 +16,10 @@
#include "BasicObjCFoundationChecks.h"
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
#include "clang/Analysis/PathSensitive/ValueState.h"
-#include "clang/Analysis/PathSensitive/AnnotatedPath.h"
+#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTContext.h"
@@ -28,15 +29,73 @@
#include <sstream>
using namespace clang;
+
+static ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) {
+ Expr* Receiver = ME->getReceiver();
+
+ if (!Receiver)
+ return NULL;
+
+ assert (Receiver->getType()->isPointerType());
+
+ const PointerType* T = Receiver->getType()->getAsPointerType();
+ return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr());
+}
+
+static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
+ ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
+ return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName()
+ : NULL;
+}
+
namespace {
+class VISIBILITY_HIDDEN NilArg : public BugDescription {
+ std::string Msg;
+ const char* s;
+ SourceRange R;
+public:
+ NilArg(ObjCMessageExpr* ME, unsigned Arg);
+ virtual ~NilArg() {}
+
+ virtual const char* getName() const {
+ return "nil argument";
+ }
+
+ virtual const char* getDescription() const {
+ return s;
+ }
+
+ virtual void getRanges(const SourceRange*& beg,
+ const SourceRange*& end) const {
+ beg = &R;
+ end = beg+1;
+ }
+
+};
+
+NilArg::NilArg(ObjCMessageExpr* ME, unsigned Arg) : s(NULL) {
+
+ Expr* E = ME->getArg(Arg);
+ R = E->getSourceRange();
+
+ std::ostringstream os;
+
+ os << "Argument to '" << GetReceiverNameType(ME) << "' method '"
+ << ME->getSelector().getName() << "' cannot be nil.";
+
+ Msg = os.str();
+ s = Msg.c_str();
+}
+
+
class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck {
ASTContext &Ctx;
ValueStateManager* VMgr;
- typedef std::list<AnnotatedPath<ValueState> > ErrorsTy;
+ typedef std::vector<std::pair<NodeTy*,BugDescription*> > ErrorsTy;
ErrorsTy Errors;
RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
@@ -53,12 +112,26 @@
BasicObjCFoundationChecks(ASTContext& ctx, ValueStateManager* vmgr)
: Ctx(ctx), VMgr(vmgr) {}
- virtual ~BasicObjCFoundationChecks() {}
+ virtual ~BasicObjCFoundationChecks() {
+ for (ErrorsTy::iterator I = Errors.begin(), E = Errors.end(); I!=E; ++I)
+ delete I->second;
+ }
virtual bool Audit(ExplodedNode<ValueState>* N);
- virtual void ReportResults(Diagnostic& D);
-
+ virtual void ReportResults(Diagnostic& Diag, PathDiagnosticClient* PD,
+ ASTContext& Ctx, BugReporter& BR,
+ ExplodedGraph<GRExprEngine>& G);
+
+private:
+
+ void AddError(NodeTy* N, BugDescription* D) {
+ Errors.push_back(std::make_pair(N, D));
+ }
+
+ void WarnNilArg(NodeTy* N, ObjCMessageExpr* ME, unsigned Arg) {
+ AddError(N, new NilArg(ME, Arg));
+ }
};
} // end anonymous namespace
@@ -71,24 +144,7 @@
return new BasicObjCFoundationChecks(Ctx, VMgr);
}
-static ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) {
- Expr* Receiver = ME->getReceiver();
-
- if (!Receiver)
- return NULL;
-
- assert (Receiver->getType()->isPointerType());
-
- const PointerType* T = Receiver->getType()->getAsPointerType();
-
- return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr());
-}
-static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
- ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
- return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName()
- : NULL;
-}
bool BasicObjCFoundationChecks::Audit(ExplodedNode<ValueState>* N) {
@@ -127,43 +183,13 @@
//===----------------------------------------------------------------------===//
-void BasicObjCFoundationChecks::Warn(NodeTy* N, Expr* E, const std::string& s) {
- Errors.push_back(AnnotatedPath<ValueState>());
- Errors.back().push_back(N, s, E);
-}
-
-void BasicObjCFoundationChecks::ReportResults(Diagnostic& D) {
-
- // FIXME: Expand errors into paths. For now, just issue warnings.
-
- for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I) {
-
- AnnotatedNode<ValueState>& AN = I->back();
-
- unsigned diag = D.getCustomDiagID(Diagnostic::Warning,
- AN.getString().c_str());
-
- Stmt* S = cast<PostStmt>(AN.getNode()->getLocation()).getStmt();
- FullSourceLoc L(S->getLocStart(), Ctx.getSourceManager());
-
- SourceRange R = AN.getExpr()->getSourceRange();
+void BasicObjCFoundationChecks::ReportResults(Diagnostic& Diag,
+ PathDiagnosticClient* PD,
+ ASTContext& Ctx, BugReporter& BR,
+ ExplodedGraph<GRExprEngine>& G) {
- D.Report(L, diag, &AN.getString(), 1, &R, 1);
- }
-}
-
-void BasicObjCFoundationChecks::WarnNilArg(NodeTy* N, Expr* E) {
-
- ObjCMessageExpr* ME =
- cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
-
- std::ostringstream os;
-
- os << "Argument to '" << GetReceiverNameType(ME) << "' method '"
- << ME->getSelector().getName()
- << "' cannot be nil.";
-
- Warn(N, E, os.str());
+ for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I)
+ BR.EmitPathWarning(Diag, PD, Ctx, *I->second, G, I->first);
}
bool BasicObjCFoundationChecks::CheckNilArg(NodeTy* N, unsigned Arg) {
@@ -173,7 +199,7 @@
Expr * E = ME->getArg(Arg);
if (isNil(GetRVal(N->getState(), E))) {
- WarnNilArg(N, E);
+ WarnNilArg(N, ME, Arg);
return true;
}
Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=49180&r1=49179&r2=49180&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Thu Apr 3 12:57:38 2008
@@ -43,8 +43,7 @@
PathDiagnosticPiece*
-BugDescription::getEndPath(ASTContext& Ctx,
- ExplodedNode<ValueState> *N) const {
+BugDescription::getEndPath(ASTContext& Ctx, ExplodedNode<ValueState> *N) const {
Stmt* S = GetStmt(N->getLocation());
@@ -60,6 +59,12 @@
return P;
}
+void BugDescription::getRanges(const SourceRange*& beg,
+ const SourceRange*& end) const {
+ beg = NULL;
+ end = NULL;
+}
+
void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
const BugDescription& B,
ExplodedGraph<GRExprEngine>& G,
@@ -266,7 +271,7 @@
return;
std::ostringstream os;
- os << "[CHECKER] " << B.getName();
+ os << "[CHECKER] " << B.getDescription();
unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning,
os.str().c_str());
Modified: cfe/trunk/lib/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRSimpleVals.cpp?rev=49180&r1=49179&r2=49180&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.cpp Thu Apr 3 12:57:38 2008
@@ -164,8 +164,8 @@
namespace clang {
unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
- Diagnostic& Diag, PathDiagnosticClient* PD,
- bool Visualize, bool TrimGraph) {
+ Diagnostic& Diag, PathDiagnosticClient* PD,
+ bool Visualize, bool TrimGraph) {
GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
GRExprEngine* CS = &Eng.getCheckerState();
@@ -217,7 +217,8 @@
EmitWarning(Diag, PD, Ctx, BR, RetStack(), G,
CS->ret_stackaddr_begin(), CS->ret_stackaddr_end());
- FoundationCheck.get()->ReportResults(Diag);
+
+ FoundationCheck.get()->ReportResults(Diag, PD, Ctx, BR, G);
#ifndef NDEBUG
if (Visualize) CS->ViewGraph(TrimGraph);
#endif
Modified: cfe/trunk/lib/Analysis/GRSimpleVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRSimpleVals.h?rev=49180&r1=49179&r2=49180&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.h (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.h Thu Apr 3 12:57:38 2008
@@ -21,6 +21,9 @@
namespace clang {
+class PathDiagnostic;
+class ASTContext;
+
class GRSimpleVals : public GRTransferFuncs {
public:
GRSimpleVals() {}
@@ -58,6 +61,9 @@
CallExpr* CE, LVal L,
ExplodedNode<ValueState>* Pred);
+ static void GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
+ ExplodedNode<ValueState>* N);
+
protected:
// Equality operators for LVals.
More information about the cfe-commits
mailing list