aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/BugReporter.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-04-23 23:35:07 +0000
committerTed Kremenek <kremenek@apple.com>2008-04-23 23:35:07 +0000
commit5a429954aedd8a830a70fcea2cb51561673e4fc3 (patch)
treeb180dacc17a940490263c631106505120296220c /lib/Analysis/BugReporter.cpp
parent6aaca9cbf2e3f3c976e0c685078a22420c416f5e (diff)
For case statements involving enums, BugReporter now generates PathDiagnostics
that say that we are jumping to "case a" instead of "case 0". This is a feature implementation for <rdar://problem/5880430>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50197 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BugReporter.cpp')
-rw-r--r--lib/Analysis/BugReporter.cpp70
1 files changed, 38 insertions, 32 deletions
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index 33633736b1..d213d993f3 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -254,16 +254,16 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
case Stmt::SwitchStmtClass: {
// Figure out what case arm we took.
-
- Stmt* S = Dst->getLabel();
-
- if (!S)
- continue;
-
+
std::ostringstream os;
-
- switch (S->getStmtClass()) {
+
+ if (Stmt* S = Dst->getLabel())
+ switch (S->getStmtClass()) {
+
default:
+ assert(false && "Not a valid switch label.");
+ continue;
+
case Stmt::DefaultStmtClass: {
os << "Control jumps to the 'default' case at line "
@@ -276,38 +276,45 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
os << "Control jumps to 'case ";
- Expr* CondE = cast<SwitchStmt>(T)->getCond();
- unsigned bits = Ctx.getTypeSize(CondE->getType());
+ CaseStmt* Case = cast<CaseStmt>(S);
+ Expr* LHS = Case->getLHS()->IgnoreParenCasts();
- llvm::APSInt V1(bits, false);
+ // Determine if it is an enum.
- CaseStmt* Case = cast<CaseStmt>(S);
+ bool GetRawInt = true;
- if (!Case->getLHS()->isIntegerConstantExpr(V1, Ctx, 0, true)) {
- assert (false &&
- "Case condition must evaluate to an integer constant.");
- continue;
+ if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
+
+ // FIXME: Maybe this should be an assertion. Are there cases
+ // were it is not an EnumConstantDecl?
+
+ EnumConstantDecl* D = dyn_cast<EnumConstantDecl>(DR->getDecl());
+
+ if (D) {
+ GetRawInt = false;
+ os << D->getName();
+ }
}
+
+ if (GetRawInt) {
- os << V1.toString();
-
- // Get the RHS of the case, if it exists.
-
- if (Expr* E = Case->getRHS()) {
-
- llvm::APSInt V2(bits, false);
+ // Not an enum.
+ Expr* CondE = cast<SwitchStmt>(T)->getCond();
+ unsigned bits = Ctx.getTypeSize(CondE->getType());
+ llvm::APSInt V(bits, false);
- if (!E->isIntegerConstantExpr(V2, Ctx, 0, true)) {
- assert (false &&
- "Case condition (RHS) must evaluate to an integer constant.");
+ if (!LHS->isIntegerConstantExpr(V, Ctx, 0, true)) {
+ assert (false && "Case condition must be constant.");
continue;
}
- os << " .. " << V2.toString();
+ os << V.toString();
}
+
+
os << ":' at line "
- << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
+ << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
break;
@@ -381,10 +388,9 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
}
}
}
- else
- if (PathDiagnosticPiece* piece = R.VisitNode(N, NextNode,
- *ReportGraph, *this))
- PD.push_front(piece);
+
+ if (PathDiagnosticPiece* p = R.VisitNode(N, NextNode, *ReportGraph, *this))
+ PD.push_front(p);
}
}