[analyzer] Suppress bugs whose paths go through the return of a null pointer.

This is a heuristic intended to greatly reduce the number of false
positives resulting from inlining, particularly inlining of generic,
defensive C++ methods that live in header files. The suppression is
triggered in the cases where we ask to track where a null pointer came
from, and it turns out that the source of the null pointer was an inlined
function call.

This change brings the number of bug reports in LLVM from ~1500 down to
around ~300, a much more manageable number. Yes, some true positives may
be hidden as well, but from what I looked at the vast majority of silenced
reports are false positives, and many of the true issues found by the
analyzer are still reported.

I'm hoping to improve this heuristic further by adding some exceptions
next week (cases in which a bug should still be reported).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164449 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 445500b..00d7d3b 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -140,9 +140,13 @@
   ReturnVisitor(const StackFrameContext *Frame)
     : StackFrame(Frame), Satisfied(false) {}
 
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+  static void *getTag() {
     static int Tag = 0;
-    ID.AddPointer(&Tag);
+    return static_cast<void *>(&Tag);
+  }
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(ReturnVisitor::getTag());
     ID.AddPointer(StackFrame);
   }
 
@@ -215,10 +219,6 @@
     // Don't print any more notes after this one.
     Satisfied = true;
 
-    // Build an appropriate message based on the return value.
-    SmallString<64> Msg;
-    llvm::raw_svector_ostream Out(Msg);
-
     const Expr *RetE = Ret->getRetValue();
     assert(RetE && "Tracking a return value for a void function");
     RetE = RetE->IgnoreParenCasts();
@@ -234,7 +234,18 @@
     // If we're returning 0, we should track where that 0 came from.
     bugreporter::trackNullOrUndefValue(N, RetE, BR);
 
+    // Build an appropriate message based on the return value.
+    SmallString<64> Msg;
+    llvm::raw_svector_ostream Out(Msg);
+
     if (isa<Loc>(V)) {
+      // If we are pruning null-return paths as unlikely error paths, mark the
+      // report invalid. We still want to emit a path note, however, in case
+      // the report is resurrected as valid later on.
+      ExprEngine &Eng = BRC.getBugReporter().getEngine();
+      if (Eng.getAnalysisManager().options.shouldPruneNullReturnPaths())
+        BR.markInvalid(ReturnVisitor::getTag(), StackFrame);
+
       if (RetE->getType()->isObjCObjectPointerType())
         Out << "Returning nil";
       else