|
@@ -58,34 +58,37 @@ public:
|
|
|
virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
|
|
|
};
|
|
|
|
|
|
-// FIXME: Combine this with RangedBugReport and remove RangedBugReport.
|
|
|
class BugReport : public BugReporterVisitor {
|
|
|
+public:
|
|
|
+ class NodeResolver {
|
|
|
+ public:
|
|
|
+ virtual ~NodeResolver() {}
|
|
|
+ virtual const ExplodedNode*
|
|
|
+ getOriginalNode(const ExplodedNode *N) = 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data,
|
|
|
+ const ExplodedNode *N);
|
|
|
+ typedef const SourceRange *ranges_iterator;
|
|
|
+
|
|
|
protected:
|
|
|
+ friend class BugReporter;
|
|
|
+ friend class BugReportEquivClass;
|
|
|
+ typedef SmallVector<std::pair<VisitorCreator, const void*>, 2> Creators;
|
|
|
+
|
|
|
BugType& BT;
|
|
|
std::string ShortDescription;
|
|
|
std::string Description;
|
|
|
const ExplodedNode *ErrorNode;
|
|
|
- mutable SourceRange R;
|
|
|
-
|
|
|
-protected:
|
|
|
- friend class BugReporter;
|
|
|
- friend class BugReportEquivClass;
|
|
|
+ SmallVector<SourceRange, 4> Ranges;
|
|
|
+ Creators creators;
|
|
|
|
|
|
/// Profile to identify equivalent bug reports for error report coalescing.
|
|
|
- virtual void Profile(llvm::FoldingSetNodeID& hash) const {
|
|
|
- hash.AddPointer(&BT);
|
|
|
- hash.AddInteger(getLocation().getRawEncoding());
|
|
|
- hash.AddString(Description);
|
|
|
- }
|
|
|
+ virtual void Profile(llvm::FoldingSetNodeID& hash) const;
|
|
|
|
|
|
-public:
|
|
|
- class NodeResolver {
|
|
|
- public:
|
|
|
- virtual ~NodeResolver() {}
|
|
|
- virtual const ExplodedNode*
|
|
|
- getOriginalNode(const ExplodedNode *N) = 0;
|
|
|
- };
|
|
|
+ const Stmt *getStmt() const;
|
|
|
|
|
|
+public:
|
|
|
BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
|
|
|
: BT(bt), Description(desc), ErrorNode(errornode) {}
|
|
|
|
|
@@ -96,34 +99,26 @@ public:
|
|
|
|
|
|
virtual ~BugReport();
|
|
|
|
|
|
- virtual bool isOwnedByReporterContext() { return false; }
|
|
|
+ bool isOwnedByReporterContext() { return false; }
|
|
|
|
|
|
const BugType& getBugType() const { return BT; }
|
|
|
BugType& getBugType() { return BT; }
|
|
|
|
|
|
- // FIXME: Perhaps this should be moved into a subclass?
|
|
|
const ExplodedNode *getErrorNode() const { return ErrorNode; }
|
|
|
|
|
|
- // FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint
|
|
|
- // object.
|
|
|
- // FIXME: If we do need it, we can probably just make it private to
|
|
|
- // BugReporter.
|
|
|
- const Stmt *getStmt() const;
|
|
|
-
|
|
|
const StringRef getDescription() const { return Description; }
|
|
|
|
|
|
const StringRef getShortDescription() const {
|
|
|
return ShortDescription.empty() ? Description : ShortDescription;
|
|
|
}
|
|
|
|
|
|
- /// \brief This allows for addition of metadata to the diagnostic.
|
|
|
+ /// \brief This allows for addition of meta data to the diagnostic.
|
|
|
///
|
|
|
/// Currently, only the HTMLDiagnosticClient knows how to display it.
|
|
|
virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
|
|
|
return std::make_pair((const char**)0,(const char**)0);
|
|
|
}
|
|
|
|
|
|
- // FIXME: Perhaps move this into a subclass.
|
|
|
/// Provide custom definition for the last diagnostic piece on the path.
|
|
|
virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
|
|
|
const ExplodedNode *N);
|
|
@@ -135,9 +130,28 @@ public:
|
|
|
/// This location is used by clients rendering diagnostics.
|
|
|
virtual SourceLocation getLocation() const;
|
|
|
|
|
|
- typedef const SourceRange *ranges_iterator;
|
|
|
+ /// \brief Add a range to a bug report.
|
|
|
+ ///
|
|
|
+ /// Ranges are used to highlight regions of interest in the source code.
|
|
|
+ /// They should be at the same source code line as the BugReport location.
|
|
|
+ void addRange(SourceRange R) {
|
|
|
+ assert(R.isValid());
|
|
|
+ Ranges.push_back(R);
|
|
|
+ }
|
|
|
|
|
|
- virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const;
|
|
|
+ /// \brief Get the SourceRanges associated with the report.
|
|
|
+ virtual std::pair<ranges_iterator, ranges_iterator> getRanges();
|
|
|
+
|
|
|
+ /// \brief Add custom or predefined bug report visitors to this report.
|
|
|
+ ///
|
|
|
+ /// The visitors should be used when the default trace is not sufficient.
|
|
|
+ /// For example, they allow constructing a more elaborate trace.
|
|
|
+ /// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
|
|
|
+ /// registerFindLastStore(), registerNilReceiverVisitor(), and
|
|
|
+ /// registerVarDeclsLastStore().
|
|
|
+ void addVisitorCreator(VisitorCreator creator, const void *data) {
|
|
|
+ creators.push_back(std::make_pair(creator, data));
|
|
|
+ }
|
|
|
|
|
|
virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
|
|
|
const ExplodedNode *PrevN,
|
|
@@ -195,91 +209,6 @@ public:
|
|
|
const_iterator end() const { return const_iterator(Reports.end()); }
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-//===----------------------------------------------------------------------===//
|
|
|
-// Specialized subclasses of BugReport.
|
|
|
-//===----------------------------------------------------------------------===//
|
|
|
-
|
|
|
-// FIXME: Collapse this with the default BugReport class.
|
|
|
-class RangedBugReport : public BugReport {
|
|
|
- SmallVector<SourceRange, 4> Ranges;
|
|
|
-public:
|
|
|
- RangedBugReport(BugType& D, StringRef description,
|
|
|
- ExplodedNode *errornode)
|
|
|
- : BugReport(D, description, errornode) {}
|
|
|
-
|
|
|
- RangedBugReport(BugType& D, StringRef shortDescription,
|
|
|
- StringRef description, ExplodedNode *errornode)
|
|
|
- : BugReport(D, shortDescription, description, errornode) {}
|
|
|
-
|
|
|
- ~RangedBugReport();
|
|
|
-
|
|
|
- // FIXME: Move this out of line.
|
|
|
- /// \brief Add a range to a bug report.
|
|
|
- ///
|
|
|
- /// Ranges are used to highlight regions of interest in the source code.
|
|
|
- /// They should be at the same source code line as the BugReport location.
|
|
|
- void addRange(SourceRange R) {
|
|
|
- assert(R.isValid());
|
|
|
- Ranges.push_back(R);
|
|
|
- }
|
|
|
-
|
|
|
- virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const {
|
|
|
- return std::make_pair(Ranges.begin(), Ranges.end());
|
|
|
- }
|
|
|
-
|
|
|
- virtual void Profile(llvm::FoldingSetNodeID& hash) const {
|
|
|
- BugReport::Profile(hash);
|
|
|
- for (SmallVectorImpl<SourceRange>::const_iterator I =
|
|
|
- Ranges.begin(), E = Ranges.end(); I != E; ++I) {
|
|
|
- const SourceRange range = *I;
|
|
|
- if (!range.isValid())
|
|
|
- continue;
|
|
|
- hash.AddInteger(range.getBegin().getRawEncoding());
|
|
|
- hash.AddInteger(range.getEnd().getRawEncoding());
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/// EnhancedBugReport allows checkers to register additional bug report
|
|
|
-/// visitors, thus, constructing a more elaborate trace.
|
|
|
-class EnhancedBugReport : public RangedBugReport {
|
|
|
-public:
|
|
|
- typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data,
|
|
|
- const ExplodedNode *N);
|
|
|
-
|
|
|
-private:
|
|
|
- typedef std::vector<std::pair<VisitorCreator, const void*> > Creators;
|
|
|
- Creators creators;
|
|
|
-
|
|
|
-public:
|
|
|
- EnhancedBugReport(BugType& D, StringRef description,
|
|
|
- ExplodedNode *errornode)
|
|
|
- : RangedBugReport(D, description, errornode) {}
|
|
|
-
|
|
|
- EnhancedBugReport(BugType& D, StringRef shortDescription,
|
|
|
- StringRef description, ExplodedNode *errornode)
|
|
|
- : RangedBugReport(D, shortDescription, description, errornode) {}
|
|
|
-
|
|
|
- ~EnhancedBugReport() {}
|
|
|
-
|
|
|
- void registerInitialVisitors(BugReporterContext &BRC, const ExplodedNode *N) {
|
|
|
- for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I)
|
|
|
- I->first(BRC, I->second, N);
|
|
|
- }
|
|
|
-
|
|
|
- /// \brief Add custom or predefined bug report visitors to this report.
|
|
|
- ///
|
|
|
- /// The visitors should be used when the default trace is not sufficient.
|
|
|
- /// For example, they allow constructing a more elaborate trace.
|
|
|
- /// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
|
|
|
- /// registerFindLastStore(), registerNilReceiverVisitor(), and
|
|
|
- /// registerVarDeclsLastStore().
|
|
|
- void addVisitorCreator(VisitorCreator creator, const void *data) {
|
|
|
- creators.push_back(std::make_pair(creator, data));
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
// BugReporter and friends.
|
|
|
//===----------------------------------------------------------------------===//
|
|
@@ -491,12 +420,12 @@ public:
|
|
|
virtual BugReport::NodeResolver& getNodeResolver() = 0;
|
|
|
};
|
|
|
|
|
|
-class DiagBugReport : public RangedBugReport {
|
|
|
+class DiagBugReport : public BugReport {
|
|
|
std::list<std::string> Strs;
|
|
|
FullSourceLoc L;
|
|
|
public:
|
|
|
DiagBugReport(BugType& D, StringRef desc, FullSourceLoc l) :
|
|
|
- RangedBugReport(D, desc, 0), L(l) {}
|
|
|
+ BugReport(D, desc, 0), L(l) {}
|
|
|
|
|
|
virtual ~DiagBugReport() {}
|
|
|
|