]> granicus.if.org Git - clang/commitdiff
Allow some BugReports to opt-out of PathDiagnostic callstack pruning until we have...
authorTed Kremenek <kremenek@apple.com>
Thu, 31 May 2012 06:03:17 +0000 (06:03 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 31 May 2012 06:03:17 +0000 (06:03 +0000)
improved the pruning heuristics.  The current heuristics are pretty good, but they make diagnostics
for uninitialized variables warnings particularly useless in some cases.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157734 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
lib/StaticAnalyzer/Core/BugReporter.cpp

index 2b699a85f8ef89012e64e945b2660ed59f4cd24b..5ee52cc61589029dcf06a811b74d5aa41d794859 100644 (file)
@@ -101,20 +101,27 @@ protected:
   /// Used for clients to tell if the report's configuration has changed
   /// since the last time they checked.
   unsigned ConfigurationChangeToken;
+  
+  /// When set, this flag disables all callstack pruning from a diagnostic
+  /// path.  This is useful for some reports that want maximum fidelty
+  /// when reporting an issue.
+  bool DoNotPrunePath;
 
 public:
   BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
     : BT(bt), DeclWithIssue(0), Description(desc), ErrorNode(errornode),
-      ConfigurationChangeToken(0) {}
+      ConfigurationChangeToken(0), DoNotPrunePath(false) {}
 
   BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
             const ExplodedNode *errornode)
     : BT(bt), DeclWithIssue(0), ShortDescription(shortDesc), Description(desc),
-      ErrorNode(errornode), ConfigurationChangeToken(0) {}
+      ErrorNode(errornode), ConfigurationChangeToken(0),
+      DoNotPrunePath(false) {}
 
   BugReport(BugType& bt, StringRef desc, PathDiagnosticLocation l)
     : BT(bt), DeclWithIssue(0), Description(desc), Location(l), ErrorNode(0),
-      ConfigurationChangeToken(0) {}
+      ConfigurationChangeToken(0),
+      DoNotPrunePath(false) {}
 
   /// \brief Create a BugReport with a custom uniqueing location.
   ///
@@ -142,6 +149,13 @@ public:
     return ShortDescription.empty() ? Description : ShortDescription;
   }
 
+  /// Indicates whether or not any path pruning should take place
+  /// when generating a PathDiagnostic from this BugReport.
+  bool shouldPrunePath() const { return !DoNotPrunePath; }
+
+  /// Disable all path pruning when generating a PathDiagnostic.
+  void disablePathPruning() { DoNotPrunePath = true; }
+  
   void markInteresting(SymbolRef sym);
   void markInteresting(const MemRegion *R);
   void markInteresting(SVal V);
index 81a27451cbaab9b4df1c49cb8ad0325e8b238186..9b56c9fe137b2c8adf85009f19d52abc13ee3439 100644 (file)
@@ -88,6 +88,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
       report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
                                         bugreporter::GetDerefExpr(N), report));
+      report->disablePathPruning();
       C.EmitReport(report);
     }
     return;
index a30f6d53287f127fdf8d77122cc8a18fe65a4499..48b194107e9cae64a0fbec71416ab8cf8ff3d61c 100644 (file)
@@ -101,6 +101,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
       BugReport *R = new BugReport(*BT, BT->getDescription(), N);
       R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex, R));
       R->addRange(Ex->getSourceRange());
+      R->disablePathPruning();
 
       Ctx.EmitReport(R);
     }
index d57767eec9fbf5c81b0ebf6d48e3efca309d83f9..675b38a5df266be67407df5431b63ef2dc4895cf 100644 (file)
@@ -94,6 +94,7 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
         if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD))
           R->addRange(Ex->getSourceRange());
         R->addVisitor(new FindLastStoreBRVisitor(VRVal, VR));
+        R->disablePathPruning();
         // need location of block
         C.EmitReport(R);
       }
index 78f7fa61b288b91103d64c92216ac35757f85468..7b1081f6bb3d8f3ea67836dd63b5842d595f636d 100644 (file)
@@ -80,6 +80,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
     R->addRange(ex->getSourceRange());
     R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, ex, R));
   }
+  R->disablePathPruning();
   C.EmitReport(R);
 }
 
index c774818edf2feba732b780fc54ebf4cb6cdfd185..14fcb179cce7f4b97ef4994e1d284d9b33db4052 100644 (file)
@@ -1861,9 +1861,11 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
   } while(finalReportConfigToken != originalReportConfigToken);
 
   // Finally, prune the diagnostic path of uninteresting stuff.
-  bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces());
-  assert(hasSomethingInteresting);
-  (void) hasSomethingInteresting;
+  if (R->shouldPrunePath()) {
+    bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces());
+    assert(hasSomethingInteresting);
+    (void) hasSomethingInteresting;
+  }
 }
 
 void BugReporter::Register(BugType *BT) {