diff options
author | David Blaikie <dblaikie@gmail.com> | 2012-01-22 02:31:55 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2012-01-22 02:31:55 +0000 |
commit | 9366750a5a97c8aeae1df4898ea849b087865195 (patch) | |
tree | ebac52c117547e3b9ba7e42bc151c3f9eaa06a05 /lib/Sema/SemaStmt.cpp | |
parent | adabbca569bd6c6dfe91773dea8cf7d14cb4cc5e (diff) |
Fix -Wswitch to warn about out of bounds enum cases even when there's a default
For consistency with GCC & reasonable sanity. The FIXME suggests that the
original author was perhaps using the default check for some other purpose,
not realizing the more obvious limitation/false-negatives it creates, but this
doesn't seem to produce any regressions & fixes the included test.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148649 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 0be3e43b5a..b9b5b212c3 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -862,39 +862,35 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals); // See which case values aren't in enum. - // TODO: we might want to check whether case values are out of the - // enum even if we don't want to check whether all cases are handled. - if (!TheDefaultStmt) { - EnumValsTy::const_iterator EI = EnumVals.begin(); - for (CaseValsTy::const_iterator CI = CaseVals.begin(); - CI != CaseVals.end(); CI++) { - while (EI != EIend && EI->first < CI->first) - EI++; - if (EI == EIend || EI->first > CI->first) - Diag(CI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum) - << ED->getDeclName(); + EnumValsTy::const_iterator EI = EnumVals.begin(); + for (CaseValsTy::const_iterator CI = CaseVals.begin(); + CI != CaseVals.end(); CI++) { + while (EI != EIend && EI->first < CI->first) + EI++; + if (EI == EIend || EI->first > CI->first) + Diag(CI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum) + << ED->getDeclName(); + } + // See which of case ranges aren't in enum + EI = EnumVals.begin(); + for (CaseRangesTy::const_iterator RI = CaseRanges.begin(); + RI != CaseRanges.end() && EI != EIend; RI++) { + while (EI != EIend && EI->first < RI->first) + EI++; + + if (EI == EIend || EI->first != RI->first) { + Diag(RI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum) + << ED->getDeclName(); } - // See which of case ranges aren't in enum - EI = EnumVals.begin(); - for (CaseRangesTy::const_iterator RI = CaseRanges.begin(); - RI != CaseRanges.end() && EI != EIend; RI++) { - while (EI != EIend && EI->first < RI->first) - EI++; - - if (EI == EIend || EI->first != RI->first) { - Diag(RI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum) - << ED->getDeclName(); - } - llvm::APSInt Hi = - RI->second->getRHS()->EvaluateKnownConstInt(Context); - AdjustAPSInt(Hi, CondWidth, CondIsSigned); - while (EI != EIend && EI->first < Hi) - EI++; - if (EI == EIend || EI->first != Hi) - Diag(RI->second->getRHS()->getExprLoc(), diag::warn_not_in_enum) - << ED->getDeclName(); - } + llvm::APSInt Hi = + RI->second->getRHS()->EvaluateKnownConstInt(Context); + AdjustAPSInt(Hi, CondWidth, CondIsSigned); + while (EI != EIend && EI->first < Hi) + EI++; + if (EI == EIend || EI->first != Hi) + Diag(RI->second->getRHS()->getExprLoc(), diag::warn_not_in_enum) + << ED->getDeclName(); } // Check which enum vals aren't in switch @@ -904,7 +900,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, SmallVector<DeclarationName,8> UnhandledNames; - for (EnumValsTy::const_iterator EI = EnumVals.begin(); EI != EIend; EI++){ + for (EI = EnumVals.begin(); EI != EIend; EI++){ // Drop unneeded case values llvm::APSInt CIVal; while (CI != CaseVals.end() && CI->first < EI->first) |