diff options
| author | Ted Kremenek <kremenek@apple.com> | 2010-03-20 18:02:01 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2010-03-20 18:02:01 +0000 |
| commit | 3460b539df8a9052b4502d65f1db01f549047e20 (patch) | |
| tree | 96754dc60cec30f3b40c677d7b3ebe1a5d0936ae /clang/lib/Checker | |
| parent | 92713e7ec33e4d7c3ef61b9fb2768a26eb811765 (diff) | |
| download | bcm5719-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.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Checker/BugReporterVisitors.cpp | 49 |
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()); +} |

