aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-04-09 00:20:43 +0000
committerTed Kremenek <kremenek@apple.com>2008-04-09 00:20:43 +0000
commit6837faa083bebad39aa342f84c2b450fb6410eaf (patch)
tree00f153a96414c920984d115631dbdfc94fd94708
parentf5749aa30bf39cc56f6fe98ce2e773e9338f5d04 (diff)
Added new "BugReporterHelper" class which is used by BugReporter to emit
checker-specific diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49412 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h18
-rw-r--r--lib/Analysis/BugReporter.cpp32
2 files changed, 40 insertions, 10 deletions
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index a5af327195..7ff79fc53d 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -46,6 +46,16 @@ public:
const SourceRange*& end) const;
};
+class BugReporterHelper {
+public:
+ virtual ~BugReporterHelper() {}
+
+ virtual PathDiagnosticPiece* VisitNode(ExplodedNode<ValueState>* N,
+ ExplodedNode<ValueState>* PrevN,
+ ExplodedGraph<GRExprEngine>& G,
+ ASTContext& Ctx) = 0;
+};
+
class BugReporter {
llvm::SmallPtrSet<void*,10> CachedErrors;
@@ -56,7 +66,9 @@ public:
void EmitPathWarning(Diagnostic& Diag, PathDiagnosticClient* PDC,
ASTContext& Ctx, const BugDescription& B,
ExplodedGraph<GRExprEngine>& G,
- ExplodedNode<ValueState>* N);
+ ExplodedNode<ValueState>* N,
+ BugReporterHelper** BegHelpers = NULL,
+ BugReporterHelper** EndHelpers = NULL);
void EmitWarning(Diagnostic& Diag, ASTContext& Ctx,
const BugDescription& B,
@@ -69,7 +81,9 @@ private:
void GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
const BugDescription& B,
ExplodedGraph<GRExprEngine>& G,
- ExplodedNode<ValueState>* N);
+ ExplodedNode<ValueState>* N,
+ BugReporterHelper** BegHelpers = NULL,
+ BugReporterHelper** EndHelpers = NULL);
};
} // end clang namespace
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index 14f98fa1f4..66b1b04c9d 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -83,7 +83,9 @@ void BugDescription::getRanges(const SourceRange*& beg,
void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
const BugDescription& B,
ExplodedGraph<GRExprEngine>& G,
- ExplodedNode<ValueState>* N) {
+ ExplodedNode<ValueState>* N,
+ BugReporterHelper** BegHelpers,
+ BugReporterHelper** EndHelpers) {
if (PathDiagnosticPiece* Piece = B.getEndPath(Ctx,N))
PD.push_back(Piece);
@@ -112,11 +114,15 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
assert (NewN->getLocation() == N->getLocation());
N = NewN;
-
- while (!N->pred_empty()) {
+
+ ExplodedNode<ValueState>* NextNode = N->pred_empty()
+ ? NULL : *(N->pred_begin());
+
+ while (NextNode) {
ExplodedNode<ValueState>* LastNode = N;
- N = *(N->pred_begin());
+ N = NextNode;
+ NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
ProgramPoint P = N->getLocation();
@@ -171,7 +177,7 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
case Stmt::DefaultStmtClass: {
os << "Control jumps to the 'default' case at line "
- << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
+ << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
break;
}
@@ -284,7 +290,15 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
break;
}
}
- }
+ }
+ else
+ for (BugReporterHelper** I = BegHelpers; I != EndHelpers; ++I) {
+
+ PathDiagnosticPiece* piece = (*I)->VisitNode(N, NextNode, G, Ctx);
+
+ if (piece)
+ PD.push_front(piece);
+ }
}
}
@@ -309,7 +323,9 @@ void BugReporter::EmitPathWarning(Diagnostic& Diag,
ASTContext& Ctx,
const BugDescription& B,
ExplodedGraph<GRExprEngine>& G,
- ExplodedNode<ValueState>* N) {
+ ExplodedNode<ValueState>* N,
+ BugReporterHelper** BegHelpers,
+ BugReporterHelper** EndHelpers) {
if (!PDC) {
EmitWarning(Diag, Ctx, B, N);
@@ -320,7 +336,7 @@ void BugReporter::EmitPathWarning(Diagnostic& Diag,
return;
PathDiagnostic D(B.getName());
- GeneratePathDiagnostic(D, Ctx, B, G, N);
+ GeneratePathDiagnostic(D, Ctx, B, G, N, BegHelpers, EndHelpers);
if (!D.empty())
PDC->HandlePathDiagnostic(D);