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
This commit is contained in:
Ted Kremenek 2008-04-25 19:01:27 +00:00
Родитель ce2e33258a
Коммит 2673c9ff76
1 изменённых файлов: 28 добавлений и 10 удалений

Просмотреть файл

@ -48,8 +48,12 @@ static inline Stmt* GetStmt(const ProgramPoint& P) {
} }
static inline Stmt* GetStmt(const CFGBlock* B) { static inline Stmt* GetStmt(const CFGBlock* B) {
assert (!B->empty()); if (B->empty()) {
return (*B)[0]; assert (B->getTerminator() && "Empty block should have a terminator.");
return const_cast<Stmt*>(B->getTerminator());
}
else
return (*B)[0];
} }
Stmt* BugReport::getStmt() const { Stmt* BugReport::getStmt() const {
@ -60,7 +64,18 @@ static inline ExplodedNode<ValueState>*
GetNextNode(ExplodedNode<ValueState>* N) { GetNextNode(ExplodedNode<ValueState>* N) {
return N->pred_empty() ? NULL : *(N->pred_begin()); 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) { static Stmt* GetLastStmt(ExplodedNode<ValueState>* N) {
assert (isa<BlockEntrance>(N->getLocation())); assert (isa<BlockEntrance>(N->getLocation()));
@ -311,9 +326,7 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
} }
os << V.toString(); os << V.toString();
} }
os << ":' at line " os << ":' at line "
<< SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n"; << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
@ -323,16 +336,21 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
} }
} }
else { else {
os << "'Default' branch taken.";
// FIXME: Get line number. ExecutionContinues(os, SMgr, LastNode);
os << "'Default' branch taken. "
"Execution continues after switch statement.";
} }
PD.push_front(new PathDiagnosticPiece(L, os.str())); PD.push_front(new PathDiagnosticPiece(L, os.str()));
break; 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: { case Stmt::ConditionalOperatorClass: {