aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/BugReporter.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-04-25 19:01:27 +0000
committerTed Kremenek <kremenek@apple.com>2008-04-25 19:01:27 +0000
commit2673c9ff76ebdb72b7f846e2ff1e0f4256372e19 (patch)
tree1c1aed8590a4109b69445cf7b6ff3cbb921349e3 /lib/Analysis/BugReporter.cpp
parentce2e33258a00ecea14c87995cb981c1e816d3df4 (diff)
Fix bug in BugReporter where we didn't handle emitting diagnostics for
empty CFGBlocks that only contained a terminator. Added improved diagnostics for break and continue statements and default branches in switch statements. This fixes <rdar://problem/5889244>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50286 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BugReporter.cpp')
-rw-r--r--lib/Analysis/BugReporter.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index 9c55333e4c..d00d329e95 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -48,8 +48,12 @@ static inline Stmt* GetStmt(const ProgramPoint& P) {
}
static inline Stmt* GetStmt(const CFGBlock* B) {
- assert (!B->empty());
- return (*B)[0];
+ if (B->empty()) {
+ assert (B->getTerminator() && "Empty block should have a terminator.");
+ return const_cast<Stmt*>(B->getTerminator());
+ }
+ else
+ return (*B)[0];
}
Stmt* BugReport::getStmt() const {
@@ -60,7 +64,18 @@ static inline ExplodedNode<ValueState>*
GetNextNode(ExplodedNode<ValueState>* N) {
return N->pred_empty() ? NULL : *(N->pred_begin());
}
+
+static void ExecutionContinues(std::ostream& os, SourceManager& SMgr,
+ ExplodedNode<ValueState>* N) {
+
+ Stmt* S = GetStmt(N->getLocation());
+ if (!S)
+ return;
+
+ os << "Execution continue on line "
+ << SMgr.getLogicalLineNumber(S->getLocStart()) << '.';
+}
static Stmt* GetLastStmt(ExplodedNode<ValueState>* N) {
assert (isa<BlockEntrance>(N->getLocation()));
@@ -311,9 +326,7 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
}
os << V.toString();
- }
-
-
+ }
os << ":' at line "
<< SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
@@ -323,16 +336,21 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
}
}
else {
-
- // FIXME: Get line number.
-
- os << "'Default' branch taken. "
- "Execution continues after switch statement.";
+ os << "'Default' branch taken.";
+ ExecutionContinues(os, SMgr, LastNode);
}
PD.push_front(new PathDiagnosticPiece(L, os.str()));
break;
}
+
+ case Stmt::BreakStmtClass:
+ case Stmt::ContinueStmtClass: {
+ std::ostringstream os;
+ ExecutionContinues(os, SMgr, LastNode);
+ PD.push_front(new PathDiagnosticPiece(L, os.str()));
+ break;
+ }
case Stmt::ConditionalOperatorClass: {