forked from OSchip/llvm-project
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:
parent
bff0167a0b
commit
47187c6ad2
|
@ -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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue