]> granicus.if.org Git - clang/commitdiff
BugReporter/PathDiagnostics:
authorTed Kremenek <kremenek@apple.com>
Wed, 29 Apr 2009 21:58:13 +0000 (21:58 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 29 Apr 2009 21:58:13 +0000 (21:58 +0000)
- Add an (optional) short description for BugReports for clients that want
  to distinguish between long and short descriptions for bugs
- Make the bug report for VLA less obscene for Plist diagnostics by using
  the short description

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

include/clang/Analysis/PathDiagnostic.h
include/clang/Analysis/PathSensitive/BugReporter.h
lib/Analysis/BugReporter.cpp
lib/Analysis/GRExprEngineInternalChecks.cpp
lib/Frontend/PlistDiagnostics.cpp

index 84fe8d92c60d379a1a6ae6f48b8076ddacaedada..16b9b06f7b13835dd0917f949c420db7b73f1c35 100644 (file)
@@ -50,6 +50,7 @@ public:
   virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }   
   virtual bool supportsLogicalOpControlFlow() const { return false; }
   virtual bool supportsAllBlockEdges() const { return false; }
+  virtual bool useVerboseDescription() const { return true; }
 };  
   
 //===----------------------------------------------------------------------===//
index 85430e366ef15c0b7bba61acbcef61f134eec69a..f941a7a570875f59d580fa795603c02d87f0eec0 100644 (file)
@@ -48,6 +48,7 @@ class ParentMap;
 class BugReport {
 protected:
   BugType& BT;
+  std::string ShortDescription;
   std::string Description;
   const ExplodedNode<GRState> *EndNode;
   SourceRange R;
@@ -70,6 +71,11 @@ public:
   
   BugReport(BugType& bt, const char* desc, const ExplodedNode<GRState> *n)
     : BT(bt), Description(desc), EndNode(n) {}
+  
+  BugReport(BugType& bt, const char* shortDesc, const char* desc,
+            const ExplodedNode<GRState> *n)
+  : BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
+
 
   virtual ~BugReport();
 
@@ -84,6 +90,10 @@ public:
   Stmt* getStmt(BugReporter& BR) const;
   
   const std::string& getDescription() const { return Description; }
+
+  const std::string& getShortDescription() const {
+    return ShortDescription.empty() ? Description : ShortDescription;
+  }
   
   // FIXME: Is this needed?
   virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
@@ -197,6 +207,10 @@ public:
   RangedBugReport(BugType& D, const char* description, ExplodedNode<GRState> *n)
     : BugReport(D, description, n) {}
   
+  RangedBugReport(BugType& D, const char *shortDescription,
+                  const char *description, ExplodedNode<GRState> *n)
+  : BugReport(D, shortDescription, description, n) {}
+  
   ~RangedBugReport();
 
   // FIXME: Move this out of line.
index 3c814dbb67bd00eea172e413d7d1b4be1f8591d6..4e88baab574838980f690c5726745581612adb63 100644 (file)
@@ -1667,14 +1667,18 @@ void BugReporter::EmitReport(BugReport* R) {
 void BugReporter::FlushReport(BugReportEquivClass& EQ) {
   assert(!EQ.Reports.empty());
   BugReport &R = **EQ.begin();
+  PathDiagnosticClient* PD = getPathDiagnosticClient();
   
   // FIXME: Make sure we use the 'R' for the path that was actually used.
   // Probably doesn't make a difference in practice.  
   BugType& BT = R.getBugType();
   
-  llvm::OwningPtr<PathDiagnostic> D(new PathDiagnostic(R.getBugType().getName(),
-                                                R.getDescription(),
-                                                BT.getCategory()));
+  llvm::OwningPtr<PathDiagnostic>
+    D(new PathDiagnostic(R.getBugType().getName(),
+                         PD->useVerboseDescription()
+                         ? R.getDescription() : R.getShortDescription(),
+                         BT.getCategory()));
+
   GeneratePathDiagnostic(*D.get(), EQ);
   
   // Get the meta data.
@@ -1682,7 +1686,6 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) {
   for (const char** s = Meta.first; s != Meta.second; ++s) D->addMeta(*s);
 
   // Emit a summary diagnostic to the regular Diagnostics engine.
-  PathDiagnosticClient* PD = getPathDiagnosticClient();
   const SourceRange *Beg = 0, *End = 0;
   R.getRanges(*this, Beg, End);    
   Diagnostic& Diag = getDiagnostic();
index 1b03149204188e13ee8ad5c3627c890b1d9daf1b..a40eff8fc42c9c5d8bdfc80cf05e091da0c441d1 100644 (file)
@@ -405,12 +405,23 @@ public:
             "variable-length array (VLA) '"
          << VD->getNameAsString() << "' evaluates to ";
       
-      if (Eng.getStateManager().GetSVal(N->getState(), SizeExpr).isUndef())
+      bool isUndefined = Eng.getStateManager().GetSVal(N->getState(),
+                                                       SizeExpr).isUndef();
+      
+      if (isUndefined)
         os << "an undefined or garbage value.";
       else
         os << "0. VLAs with no elements have undefined behavior.";
-
-      RangedBugReport *report = new RangedBugReport(*this, os.str().c_str(), N);
+      
+      std::string shortBuf;
+      llvm::raw_string_ostream os_short(shortBuf);
+      os_short << "Variable-length array '" << VD->getNameAsString() << "' "
+               << (isUndefined ? " garbage value for array size"
+                   : " has zero elements (undefined behavior)");
+
+      RangedBugReport *report = new RangedBugReport(*this,
+                                                    os_short.str().c_str(),
+                                                    os.str().c_str(), N);
       report->addRange(SizeExpr->getSourceRange());
       BR.EmitReport(report);
     }
index 7ad900e8741ccd72be7fc2db71e3b7836e4b8fb4..387ed45a9c7101b42a2e32f5403d0f56c409ae34 100644 (file)
@@ -45,6 +45,7 @@ namespace {
     PathGenerationScheme getGenerationScheme() const { return Extensive; }
     bool supportsLogicalOpControlFlow() const { return true; }
     bool supportsAllBlockEdges() const { return true; }
+    virtual bool useVerboseDescription() const { return false; }
   };  
 } // end anonymous namespace