summaryrefslogtreecommitdiffstats
path: root/clang/lib/Checker
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-03-20 18:02:01 +0000
committerTed Kremenek <kremenek@apple.com>2010-03-20 18:02:01 +0000
commit3460b539df8a9052b4502d65f1db01f549047e20 (patch)
tree96754dc60cec30f3b40c677d7b3ebe1a5d0936ae /clang/lib/Checker
parent92713e7ec33e4d7c3ef61b9fb2768a26eb811765 (diff)
downloadbcm5719-llvm-3460b539df8a9052b4502d65f1db01f549047e20.tar.gz
bcm5719-llvm-3460b539df8a9052b4502d65f1db01f549047e20.zip
Reapply r99024 (but with the memory issue now fixed).
llvm-svn: 99064
Diffstat (limited to 'clang/lib/Checker')
-rw-r--r--clang/lib/Checker/BugReporter.cpp2
-rw-r--r--clang/lib/Checker/BugReporterVisitors.cpp49
2 files changed, 51 insertions, 0 deletions
diff --git a/clang/lib/Checker/BugReporter.cpp b/clang/lib/Checker/BugReporter.cpp
index f26d16120e9..d4b150294e6 100644
--- a/clang/lib/Checker/BugReporter.cpp
+++ b/clang/lib/Checker/BugReporter.cpp
@@ -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:
diff --git a/clang/lib/Checker/BugReporterVisitors.cpp b/clang/lib/Checker/BugReporterVisitors.cpp
index 7104f91d882..1d6994b94b4 100644
--- a/clang/lib/Checker/BugReporterVisitors.cpp
+++ b/clang/lib/Checker/BugReporterVisitors.cpp
@@ -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());
+}
OpenPOWER on IntegriCloud