|
@@ -1960,23 +1960,38 @@ namespace {
|
|
//===---------===//
|
|
//===---------===//
|
|
|
|
|
|
class CFRefReportVisitor : public BugReporterVisitor {
|
|
class CFRefReportVisitor : public BugReporterVisitor {
|
|
|
|
+ protected:
|
|
SymbolRef Sym;
|
|
SymbolRef Sym;
|
|
const CFRefCount &TF;
|
|
const CFRefCount &TF;
|
|
|
|
+
|
|
public:
|
|
public:
|
|
-
|
|
|
|
CFRefReportVisitor(SymbolRef sym, const CFRefCount &tf)
|
|
CFRefReportVisitor(SymbolRef sym, const CFRefCount &tf)
|
|
: Sym(sym), TF(tf) {}
|
|
: Sym(sym), TF(tf) {}
|
|
|
|
|
|
- void Profile(llvm::FoldingSetNodeID &ID) const {
|
|
|
|
|
|
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const {
|
|
static int x = 0;
|
|
static int x = 0;
|
|
ID.AddPointer(&x);
|
|
ID.AddPointer(&x);
|
|
ID.AddPointer(Sym);
|
|
ID.AddPointer(Sym);
|
|
}
|
|
}
|
|
|
|
|
|
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
|
|
|
|
- const ExplodedNode *PrevN,
|
|
|
|
- BugReporterContext &BRC,
|
|
|
|
- BugReport &BR);
|
|
|
|
|
|
+ virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
|
|
|
|
+ const ExplodedNode *PrevN,
|
|
|
|
+ BugReporterContext &BRC,
|
|
|
|
+ BugReport &BR);
|
|
|
|
+
|
|
|
|
+ virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
|
|
|
|
+ const ExplodedNode *N,
|
|
|
|
+ BugReport &BR);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ class CFRefLeakReportVisitor : public CFRefReportVisitor {
|
|
|
|
+ public:
|
|
|
|
+ CFRefLeakReportVisitor(SymbolRef sym, const CFRefCount &tf)
|
|
|
|
+ : CFRefReportVisitor(sym, tf) {}
|
|
|
|
+
|
|
|
|
+ PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
|
|
|
|
+ const ExplodedNode *N,
|
|
|
|
+ BugReport &BR);
|
|
};
|
|
};
|
|
|
|
|
|
class CFRefReport : public BugReport {
|
|
class CFRefReport : public BugReport {
|
|
@@ -1985,9 +2000,10 @@ namespace {
|
|
const CFRefCount &TF;
|
|
const CFRefCount &TF;
|
|
public:
|
|
public:
|
|
CFRefReport(CFRefBug& D, const CFRefCount &tf,
|
|
CFRefReport(CFRefBug& D, const CFRefCount &tf,
|
|
- ExplodedNode *n, SymbolRef sym)
|
|
|
|
|
|
+ ExplodedNode *n, SymbolRef sym, bool registerVisitor = true)
|
|
: BugReport(D, D.getDescription(), n), Sym(sym), TF(tf) {
|
|
: BugReport(D, D.getDescription(), n), Sym(sym), TF(tf) {
|
|
- addVisitor(new CFRefReportVisitor(sym, tf));
|
|
|
|
|
|
+ if (registerVisitor)
|
|
|
|
+ addVisitor(new CFRefReportVisitor(sym, tf));
|
|
}
|
|
}
|
|
|
|
|
|
CFRefReport(CFRefBug& D, const CFRefCount &tf,
|
|
CFRefReport(CFRefBug& D, const CFRefCount &tf,
|
|
@@ -2011,23 +2027,18 @@ namespace {
|
|
|
|
|
|
SymbolRef getSymbol() const { return Sym; }
|
|
SymbolRef getSymbol() const { return Sym; }
|
|
|
|
|
|
- PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
|
|
|
|
- const ExplodedNode *N);
|
|
|
|
-
|
|
|
|
std::pair<const char**,const char**> getExtraDescriptiveText();
|
|
std::pair<const char**,const char**> getExtraDescriptiveText();
|
|
};
|
|
};
|
|
|
|
|
|
class CFRefLeakReport : public CFRefReport {
|
|
class CFRefLeakReport : public CFRefReport {
|
|
SourceLocation AllocSite;
|
|
SourceLocation AllocSite;
|
|
const MemRegion* AllocBinding;
|
|
const MemRegion* AllocBinding;
|
|
|
|
+
|
|
public:
|
|
public:
|
|
CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
|
CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
|
ExplodedNode *n, SymbolRef sym,
|
|
ExplodedNode *n, SymbolRef sym,
|
|
ExprEngine& Eng);
|
|
ExprEngine& Eng);
|
|
|
|
|
|
- PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
|
|
|
|
- const ExplodedNode *N);
|
|
|
|
-
|
|
|
|
SourceLocation getLocation() const { return AllocSite; }
|
|
SourceLocation getLocation() const { return AllocSite; }
|
|
};
|
|
};
|
|
} // end anonymous namespace
|
|
} // end anonymous namespace
|
|
@@ -2384,17 +2395,19 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
|
|
}
|
|
}
|
|
|
|
|
|
PathDiagnosticPiece*
|
|
PathDiagnosticPiece*
|
|
-CFRefReport::getEndPath(BugReporterContext &BRC,
|
|
|
|
- const ExplodedNode *EndN) {
|
|
|
|
|
|
+CFRefReportVisitor::getEndPath(BugReporterContext &BRC,
|
|
|
|
+ const ExplodedNode *EndN,
|
|
|
|
+ BugReport &BR) {
|
|
// Tell the BugReporterContext to report cases when the tracked symbol is
|
|
// Tell the BugReporterContext to report cases when the tracked symbol is
|
|
// assigned to different variables, etc.
|
|
// assigned to different variables, etc.
|
|
BRC.addNotableSymbol(Sym);
|
|
BRC.addNotableSymbol(Sym);
|
|
- return BugReport::getEndPath(BRC, EndN);
|
|
|
|
|
|
+ return BugReporterVisitor::getDefaultEndPath(BRC, EndN, BR);
|
|
}
|
|
}
|
|
|
|
|
|
PathDiagnosticPiece*
|
|
PathDiagnosticPiece*
|
|
-CFRefLeakReport::getEndPath(BugReporterContext &BRC,
|
|
|
|
- const ExplodedNode *EndN){
|
|
|
|
|
|
+CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
|
|
|
|
+ const ExplodedNode *EndN,
|
|
|
|
+ BugReport &BR) {
|
|
|
|
|
|
// Tell the BugReporterContext to report cases when the tracked symbol is
|
|
// Tell the BugReporterContext to report cases when the tracked symbol is
|
|
// assigned to different variables, etc.
|
|
// assigned to different variables, etc.
|
|
@@ -2493,7 +2506,7 @@ CFRefLeakReport::getEndPath(BugReporterContext &BRC,
|
|
CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
|
CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
|
ExplodedNode *n,
|
|
ExplodedNode *n,
|
|
SymbolRef sym, ExprEngine& Eng)
|
|
SymbolRef sym, ExprEngine& Eng)
|
|
-: CFRefReport(D, tf, n, sym) {
|
|
|
|
|
|
+: CFRefReport(D, tf, n, sym, false) {
|
|
|
|
|
|
// Most bug reports are cached at the location where they occurred.
|
|
// Most bug reports are cached at the location where they occurred.
|
|
// With leaks, we want to unique them by the location where they were
|
|
// With leaks, we want to unique them by the location where they were
|
|
@@ -2527,7 +2540,7 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
|
|
if (AllocBinding)
|
|
if (AllocBinding)
|
|
os << " and stored into '" << AllocBinding->getString() << '\'';
|
|
os << " and stored into '" << AllocBinding->getString() << '\'';
|
|
|
|
|
|
- addVisitor(new CFRefReportVisitor(sym, tf));
|
|
|
|
|
|
+ addVisitor(new CFRefLeakReportVisitor(sym, tf));
|
|
}
|
|
}
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|