[cfe-commits] r99024 - in /cfe/trunk: include/clang/Checker/BugReporter/BugReporter.h lib/Checker/BugReporter.cpp lib/Checker/BugReporterVisitors.cpp

Ted Kremenek kremenek at apple.com
Fri Mar 19 18:17:30 PDT 2010


Author: kremenek
Date: Fri Mar 19 20:17:30 2010
New Revision: 99024

URL: http://llvm.org/viewvc/llvm-project?rev=99024&view=rev
Log:
Augment path diagnostics to include displaying when a message expression
is not evaluated because the receiver is nil.

Modified:
    cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h
    cfe/trunk/lib/Checker/BugReporter.cpp
    cfe/trunk/lib/Checker/BugReporterVisitors.cpp

Modified: cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h?rev=99024&r1=99023&r2=99024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h (original)
+++ cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h Fri Mar 19 20:17:30 2010
@@ -467,6 +467,8 @@
 void registerFindLastStore(BugReporterContext& BRC, const void *memregion,
                            const ExplodedNode *N);
 
+void registerNilReceiverVisitor(BugReporterContext &BRC);
+
 
 } // end namespace clang::bugreporter
 

Modified: cfe/trunk/lib/Checker/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/BugReporter.cpp?rev=99024&r1=99023&r2=99024&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/BugReporter.cpp (original)
+++ cfe/trunk/lib/Checker/BugReporter.cpp Fri Mar 19 20:17:30 2010
@@ -1613,7 +1613,9 @@
   else
     return;
 
+  // Register node visitors.
   R->registerInitialVisitors(PDB, N);
+  bugreporter::registerNilReceiverVisitor(PDB);
 
   switch (PDB.getGenerationScheme()) {
     case PathDiagnosticClient::Extensive:

Modified: cfe/trunk/lib/Checker/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/BugReporterVisitors.cpp?rev=99024&r1=99023&r2=99024&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/Checker/BugReporterVisitors.cpp Fri Mar 19 20:17:30 2010
@@ -103,7 +103,6 @@
       const ExplodedNode *Node = N, *Last = NULL;
 
       for ( ; Node ; Last = Node, Node = Node->getFirstPred()) {
-
         if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
           if (const PostStmt *P = Node->getLocationAs<PostStmt>())
             if (const DeclStmt *DS = P->getStmtAs<DeclStmt>())
@@ -248,7 +247,6 @@
     // Check if in the previous state it was feasible for this constraint
     // to *not* be true.
     if (PrevN->getState()->Assume(Constraint, !Assumption)) {
-
       isSatisfied = true;
 
       // As a sanity check, make sure that the negation of the constraint
@@ -259,8 +257,8 @@
 
       // We found the transition point for the constraint.  We now need to
       // pretty-print the constraint. (work-in-progress)
-      std::string sbuf;
-      llvm::raw_string_ostream os(sbuf);
+      llvm::SmallString<256> sbuf;
+      llvm::raw_svector_ostream os(sbuf);
 
       if (isa<Loc>(Constraint)) {
         os << "Assuming pointer value is ";
@@ -365,3 +363,48 @@
 
   BRC.addVisitor(new FindLastStoreBRVisitor(V, R));
 }
+
+namespace {
+class NilReceiverVisitor : public BugReporterVisitor {
+public:
+  NilReceiverVisitor() {}
+
+  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());
+}





More information about the cfe-commits mailing list