forked from OSchip/llvm-project
Implement -Wswitch-enum correctly.
Clang previously implemented -Wswitch-enum the same as -Wswitch. This patch corrects the behavior to match GCC's. The critical/only difference being that -Wswitch-enum is not silenced by the presence of a default case in the switch. llvm-svn: 148679
This commit is contained in:
parent
33a362e0af
commit
60ac6382e0
|
@ -4945,6 +4945,20 @@ def err_duplicate_case : Error<"duplicate case value '%0'">;
|
|||
def warn_case_empty_range : Warning<"empty case range specified">;
|
||||
def warn_missing_case_for_condition :
|
||||
Warning<"no case matching constant switch condition '%0'">;
|
||||
|
||||
def warn_def_missing_case1 : Warning<
|
||||
"enumeration value %0 not handled in switch">,
|
||||
InGroup<SwitchEnum>, DefaultIgnore;
|
||||
def warn_def_missing_case2 : Warning<
|
||||
"enumeration values %0 and %1 not handled in switch">,
|
||||
InGroup<SwitchEnum>, DefaultIgnore;
|
||||
def warn_def_missing_case3 : Warning<
|
||||
"enumeration values %0, %1, and %2 not handled in switch">,
|
||||
InGroup<SwitchEnum>, DefaultIgnore;
|
||||
def warn_def_missing_cases : Warning<
|
||||
"%0 enumeration values not handled in switch: %1, %2, %3...">,
|
||||
InGroup<SwitchEnum>, DefaultIgnore;
|
||||
|
||||
def warn_missing_case1 : Warning<"enumeration value %0 not handled in switch">,
|
||||
InGroup<Switch>;
|
||||
def warn_missing_case2 : Warning<
|
||||
|
@ -4956,10 +4970,10 @@ def warn_missing_case3 : Warning<
|
|||
def warn_missing_cases : Warning<
|
||||
"%0 enumeration values not handled in switch: %1, %2, %3...">,
|
||||
InGroup<Switch>;
|
||||
|
||||
def warn_unreachable_default : Warning<
|
||||
"default is unreachable as all enumeration values are accounted for">,
|
||||
InGroup<SwitchEnumRedundantDefault>;
|
||||
|
||||
def warn_not_in_enum : Warning<"case value not in enumerated type %0">,
|
||||
InGroup<Switch>;
|
||||
def err_typecheck_statement_requires_scalar : Error<
|
||||
|
|
|
@ -924,30 +924,30 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
|
|||
}
|
||||
}
|
||||
|
||||
if (TheDefaultStmt) {
|
||||
if (UnhandledNames.size() == 0)
|
||||
Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default);
|
||||
else
|
||||
UnhandledNames.clear();
|
||||
}
|
||||
if (TheDefaultStmt && UnhandledNames.empty())
|
||||
Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default);
|
||||
|
||||
// Produce a nice diagnostic if multiple values aren't handled.
|
||||
switch (UnhandledNames.size()) {
|
||||
case 0: break;
|
||||
case 1:
|
||||
Diag(CondExpr->getExprLoc(), diag::warn_missing_case1)
|
||||
Diag(CondExpr->getExprLoc(), TheDefaultStmt
|
||||
? diag::warn_def_missing_case1 : diag::warn_missing_case1)
|
||||
<< UnhandledNames[0];
|
||||
break;
|
||||
case 2:
|
||||
Diag(CondExpr->getExprLoc(), diag::warn_missing_case2)
|
||||
Diag(CondExpr->getExprLoc(), TheDefaultStmt
|
||||
? diag::warn_def_missing_case2 : diag::warn_missing_case2)
|
||||
<< UnhandledNames[0] << UnhandledNames[1];
|
||||
break;
|
||||
case 3:
|
||||
Diag(CondExpr->getExprLoc(), diag::warn_missing_case3)
|
||||
Diag(CondExpr->getExprLoc(), TheDefaultStmt
|
||||
? diag::warn_def_missing_case3 : diag::warn_missing_case3)
|
||||
<< UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
|
||||
break;
|
||||
default:
|
||||
Diag(CondExpr->getExprLoc(), diag::warn_missing_cases)
|
||||
Diag(CondExpr->getExprLoc(), TheDefaultStmt
|
||||
? diag::warn_def_missing_cases : diag::warn_missing_cases)
|
||||
<< (unsigned)UnhandledNames.size()
|
||||
<< UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-enum -Wno-switch-enum-redundant-default %s
|
||||
|
||||
int test1() {
|
||||
enum { A, B } a;
|
||||
switch (a) { //expected-warning{{enumeration value 'B' not handled in switch}}
|
||||
case A: return 1;
|
||||
default: return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int test2() {
|
||||
enum { A, B } a;
|
||||
switch (a) {
|
||||
case A: return 1;
|
||||
case B: return 2;
|
||||
default: return 3;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue