Reapply r99024 (but with the memory issue now fixed).

llvm-svn: 99064
This commit is contained in:
Ted Kremenek 2010-03-20 18:02:01 +00:00
parent 92713e7ec3
commit 3460b539df
3 changed files with 52 additions and 0 deletions

View File

@ -472,6 +472,7 @@ void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
void registerFindLastStore(BugReporterContext& BRC, const void *memregion,
const ExplodedNode *N);
void registerNilReceiverVisitor(BugReporterContext &BRC);
} // end namespace clang::bugreporter

View File

@ -1628,7 +1628,9 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
else
return;
// Register node visitors.
R->registerInitialVisitors(PDB, N);
bugreporter::registerNilReceiverVisitor(PDB);
switch (PDB.getGenerationScheme()) {
case PathDiagnosticClient::Extensive:

View File

@ -379,3 +379,52 @@ void clang::bugreporter::registerFindLastStore(BugReporterContext& BRC,
BRC.addVisitor(new FindLastStoreBRVisitor(V, R));
}
namespace {
class NilReceiverVisitor : public BugReporterVisitor {
public:
NilReceiverVisitor() {}
void Profile(llvm::FoldingSetNodeID &ID) const {
static int x = 0;
ID.AddPointer(&x);
}
PathDiagnosticPiece* VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
BugReporterContext& BRC) {
const PostStmt *P = N->getLocationAs<PostStmt>();
if (!P)
return 0;
const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
if (!ME)
return 0;
const Expr *Receiver = ME->getReceiver();
if (!Receiver)
return 0;
const GRState *state = N->getState();
const SVal &V = state->getSVal(Receiver);
const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
if (!DV)
return 0;
state = state->Assume(*DV, true);
if (state)
return 0;
// The receiver was nil, and hence the method was skipped.
// Register a BugReporterVisitor to issue a message telling us how
// the receiver was null.
bugreporter::registerTrackNullOrUndefValue(BRC, Receiver, N);
// Issue a message saying that the method was skipped.
PathDiagnosticLocation L(Receiver, BRC.getSourceManager());
return new PathDiagnosticEventPiece(L, "No method actually called "
"because the receiver is nil");
}
};
} // end anonymous namespace
void clang::bugreporter::registerNilReceiverVisitor(BugReporterContext &BRC) {
BRC.addVisitor(new NilReceiverVisitor());
}