BugReporter/PathDiagnostics:

- 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

llvm-svn: 70415
This commit is contained in:
Ted Kremenek 2009-04-29 21:58:13 +00:00
parent bff0167a0b
commit 47187c6ad2
5 changed files with 36 additions and 6 deletions

View File

@ -50,6 +50,7 @@ public:
virtual PathGenerationScheme getGenerationScheme() const { return Minimal; } virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
virtual bool supportsLogicalOpControlFlow() const { return false; } virtual bool supportsLogicalOpControlFlow() const { return false; }
virtual bool supportsAllBlockEdges() const { return false; } virtual bool supportsAllBlockEdges() const { return false; }
virtual bool useVerboseDescription() const { return true; }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -48,6 +48,7 @@ class ParentMap;
class BugReport { class BugReport {
protected: protected:
BugType& BT; BugType& BT;
std::string ShortDescription;
std::string Description; std::string Description;
const ExplodedNode<GRState> *EndNode; const ExplodedNode<GRState> *EndNode;
SourceRange R; SourceRange R;
@ -70,6 +71,11 @@ public:
BugReport(BugType& bt, const char* desc, const ExplodedNode<GRState> *n) BugReport(BugType& bt, const char* desc, const ExplodedNode<GRState> *n)
: BT(bt), Description(desc), EndNode(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(); virtual ~BugReport();
@ -84,6 +90,10 @@ public:
Stmt* getStmt(BugReporter& BR) const; Stmt* getStmt(BugReporter& BR) const;
const std::string& getDescription() const { return Description; } const std::string& getDescription() const { return Description; }
const std::string& getShortDescription() const {
return ShortDescription.empty() ? Description : ShortDescription;
}
// FIXME: Is this needed? // FIXME: Is this needed?
virtual std::pair<const char**,const char**> getExtraDescriptiveText() { virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
@ -197,6 +207,10 @@ public:
RangedBugReport(BugType& D, const char* description, ExplodedNode<GRState> *n) RangedBugReport(BugType& D, const char* description, ExplodedNode<GRState> *n)
: BugReport(D, description, n) {} : BugReport(D, description, n) {}
RangedBugReport(BugType& D, const char *shortDescription,
const char *description, ExplodedNode<GRState> *n)
: BugReport(D, shortDescription, description, n) {}
~RangedBugReport(); ~RangedBugReport();
// FIXME: Move this out of line. // FIXME: Move this out of line.

View File

@ -1667,14 +1667,18 @@ void BugReporter::EmitReport(BugReport* R) {
void BugReporter::FlushReport(BugReportEquivClass& EQ) { void BugReporter::FlushReport(BugReportEquivClass& EQ) {
assert(!EQ.Reports.empty()); assert(!EQ.Reports.empty());
BugReport &R = **EQ.begin(); BugReport &R = **EQ.begin();
PathDiagnosticClient* PD = getPathDiagnosticClient();
// FIXME: Make sure we use the 'R' for the path that was actually used. // FIXME: Make sure we use the 'R' for the path that was actually used.
// Probably doesn't make a difference in practice. // Probably doesn't make a difference in practice.
BugType& BT = R.getBugType(); BugType& BT = R.getBugType();
llvm::OwningPtr<PathDiagnostic> D(new PathDiagnostic(R.getBugType().getName(), llvm::OwningPtr<PathDiagnostic>
R.getDescription(), D(new PathDiagnostic(R.getBugType().getName(),
BT.getCategory())); PD->useVerboseDescription()
? R.getDescription() : R.getShortDescription(),
BT.getCategory()));
GeneratePathDiagnostic(*D.get(), EQ); GeneratePathDiagnostic(*D.get(), EQ);
// Get the meta data. // 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); for (const char** s = Meta.first; s != Meta.second; ++s) D->addMeta(*s);
// Emit a summary diagnostic to the regular Diagnostics engine. // Emit a summary diagnostic to the regular Diagnostics engine.
PathDiagnosticClient* PD = getPathDiagnosticClient();
const SourceRange *Beg = 0, *End = 0; const SourceRange *Beg = 0, *End = 0;
R.getRanges(*this, Beg, End); R.getRanges(*this, Beg, End);
Diagnostic& Diag = getDiagnostic(); Diagnostic& Diag = getDiagnostic();

View File

@ -405,12 +405,23 @@ public:
"variable-length array (VLA) '" "variable-length array (VLA) '"
<< VD->getNameAsString() << "' evaluates to "; << 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."; os << "an undefined or garbage value.";
else else
os << "0. VLAs with no elements have undefined behavior."; os << "0. VLAs with no elements have undefined behavior.";
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.str().c_str(), N); RangedBugReport *report = new RangedBugReport(*this,
os_short.str().c_str(),
os.str().c_str(), N);
report->addRange(SizeExpr->getSourceRange()); report->addRange(SizeExpr->getSourceRange());
BR.EmitReport(report); BR.EmitReport(report);
} }

View File

@ -45,6 +45,7 @@ namespace {
PathGenerationScheme getGenerationScheme() const { return Extensive; } PathGenerationScheme getGenerationScheme() const { return Extensive; }
bool supportsLogicalOpControlFlow() const { return true; } bool supportsLogicalOpControlFlow() const { return true; }
bool supportsAllBlockEdges() const { return true; } bool supportsAllBlockEdges() const { return true; }
virtual bool useVerboseDescription() const { return false; }
}; };
} // end anonymous namespace } // end anonymous namespace