forked from OSchip/llvm-project
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>. llvm-svn: 50197
This commit is contained in:
parent
c107d0020d
commit
21bf6006b0
|
@ -255,15 +255,15 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||||
|
|
||||||
// Figure out what case arm we took.
|
// Figure out what case arm we took.
|
||||||
|
|
||||||
Stmt* S = Dst->getLabel();
|
|
||||||
|
|
||||||
if (!S)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
||||||
|
if (Stmt* S = Dst->getLabel())
|
||||||
switch (S->getStmtClass()) {
|
switch (S->getStmtClass()) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
assert(false && "Not a valid switch label.");
|
||||||
|
continue;
|
||||||
|
|
||||||
case Stmt::DefaultStmtClass: {
|
case Stmt::DefaultStmtClass: {
|
||||||
|
|
||||||
os << "Control jumps to the 'default' case at line "
|
os << "Control jumps to the 'default' case at line "
|
||||||
|
@ -276,35 +276,42 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||||
|
|
||||||
os << "Control jumps to 'case ";
|
os << "Control jumps to 'case ";
|
||||||
|
|
||||||
|
CaseStmt* Case = cast<CaseStmt>(S);
|
||||||
|
Expr* LHS = Case->getLHS()->IgnoreParenCasts();
|
||||||
|
|
||||||
|
// Determine if it is an enum.
|
||||||
|
|
||||||
|
bool GetRawInt = true;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
// Not an enum.
|
||||||
Expr* CondE = cast<SwitchStmt>(T)->getCond();
|
Expr* CondE = cast<SwitchStmt>(T)->getCond();
|
||||||
unsigned bits = Ctx.getTypeSize(CondE->getType());
|
unsigned bits = Ctx.getTypeSize(CondE->getType());
|
||||||
|
llvm::APSInt V(bits, false);
|
||||||
|
|
||||||
llvm::APSInt V1(bits, false);
|
if (!LHS->isIntegerConstantExpr(V, Ctx, 0, true)) {
|
||||||
|
assert (false && "Case condition must be constant.");
|
||||||
CaseStmt* Case = cast<CaseStmt>(S);
|
|
||||||
|
|
||||||
if (!Case->getLHS()->isIntegerConstantExpr(V1, Ctx, 0, true)) {
|
|
||||||
assert (false &&
|
|
||||||
"Case condition must evaluate to an integer constant.");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << V1.toString();
|
os << V.toString();
|
||||||
|
|
||||||
// Get the RHS of the case, if it exists.
|
|
||||||
|
|
||||||
if (Expr* E = Case->getRHS()) {
|
|
||||||
|
|
||||||
llvm::APSInt V2(bits, false);
|
|
||||||
|
|
||||||
if (!E->isIntegerConstantExpr(V2, Ctx, 0, true)) {
|
|
||||||
assert (false &&
|
|
||||||
"Case condition (RHS) must evaluate to an integer constant.");
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
os << " .. " << V2.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
os << ":' at line "
|
os << ":' at line "
|
||||||
<< SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
|
<< SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
|
||||||
|
@ -381,10 +388,9 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (PathDiagnosticPiece* piece = R.VisitNode(N, NextNode,
|
if (PathDiagnosticPiece* p = R.VisitNode(N, NextNode, *ReportGraph, *this))
|
||||||
*ReportGraph, *this))
|
PD.push_front(p);
|
||||||
PD.push_front(piece);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue