diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-23 23:35:07 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-23 23:35:07 +0000 |
commit | 5a429954aedd8a830a70fcea2cb51561673e4fc3 (patch) | |
tree | b180dacc17a940490263c631106505120296220c /lib/Analysis/BugReporter.cpp | |
parent | 6aaca9cbf2e3f3c976e0c685078a22420c416f5e (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.cpp | 70 |
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); } } |