From 21bf6006b054f5f8f85e73320ab852ba55d88e98 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 23 Apr 2008 23:35:07 +0000 Subject: [PATCH] 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 . llvm-svn: 50197 --- clang/lib/Analysis/BugReporter.cpp | 70 ++++++++++++++++-------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index 33633736b1d5..d213d993f3fb 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/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(T)->getCond(); - unsigned bits = Ctx.getTypeSize(CondE->getType()); + CaseStmt* Case = cast(S); + Expr* LHS = Case->getLHS()->IgnoreParenCasts(); - llvm::APSInt V1(bits, false); + // Determine if it is an enum. - CaseStmt* Case = cast(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(LHS)) { + + // FIXME: Maybe this should be an assertion. Are there cases + // were it is not an EnumConstantDecl? + + EnumConstantDecl* D = dyn_cast(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()) { + // Not an enum. + Expr* CondE = cast(T)->getCond(); + unsigned bits = Ctx.getTypeSize(CondE->getType()); + llvm::APSInt V(bits, false); - llvm::APSInt V2(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); } }