Author: dblaikie Date: Sat Jan 21 12:12:07 2012 New Revision: 148640 URL: http://llvm.org/viewvc/llvm-project?rev=148640&view=rev Log: Add -Wswitch-enum-redundant-default.
This warning acts as the complement to the main -Wswitch-enum warning (which warns whenever a switch over enum without a default doesn't cover all values of the enum) & has been an an-doc coding convention in LLVM and Clang in my experience. The purpose is to ensure there's never a "dead" default in a switch-over-enum because this would hide future -Wswitch-enum errors. The name warning has a separate flag name so it can be disabled but it's grouped under -Wswitch-enum & is on-by-default because of this. The existing violations of this rule in test cases have had the warning disabled & I've added a specific test for the new behavior (many negative cases already exist in the same test file - and none regressed - so I didn't add more). Reviewed by Ted Kremenek ( http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20120116/051690.html ) Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaStmt.cpp cfe/trunk/test/Sema/switch.c cfe/trunk/test/Sema/warn-unreachable.c cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp cfe/trunk/test/SemaCXX/return-noreturn.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=148640&r1=148639&r2=148640&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Sat Jan 21 12:12:07 2012 @@ -178,7 +178,8 @@ def : DiagGroup<"strict-prototypes">; def StrictSelector : DiagGroup<"strict-selector-match">; def MethodDuplicate : DiagGroup<"duplicate-method-match">; -def SwitchEnum : DiagGroup<"switch-enum">; +def SwitchEnumRedundantDefault : DiagGroup<"switch-enum-redundant-default">; +def SwitchEnum : DiagGroup<"switch-enum", [SwitchEnumRedundantDefault]>; def Switch : DiagGroup<"switch", [SwitchEnum]>; def Trigraphs : DiagGroup<"trigraphs">; Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=148640&r1=148639&r2=148640&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Jan 21 12:12:07 2012 @@ -4946,19 +4946,22 @@ def warn_missing_case_for_condition : Warning<"no case matching constant switch condition '%0'">; def warn_missing_case1 : Warning<"enumeration value %0 not handled in switch">, - InGroup<DiagGroup<"switch-enum"> >; + InGroup<SwitchEnum>; def warn_missing_case2 : Warning< "enumeration values %0 and %1 not handled in switch">, - InGroup<DiagGroup<"switch-enum"> >; + InGroup<SwitchEnum>; def warn_missing_case3 : Warning< "enumeration values %0, %1, and %2 not handled in switch">, - InGroup<DiagGroup<"switch-enum"> >; + InGroup<SwitchEnum>; def warn_missing_cases : Warning< "%0 enumeration values not handled in switch: %1, %2, %3...">, - InGroup<DiagGroup<"switch-enum"> >; + InGroup<SwitchEnum>; +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<DiagGroup<"switch-enum"> >; + InGroup<SwitchEnum>; def err_typecheck_statement_requires_scalar : Error< "statement requires expression of scalar type (%0 invalid)">; def err_typecheck_statement_requires_integer : Error< Modified: cfe/trunk/lib/Sema/SemaStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=148640&r1=148639&r2=148640&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) +++ cfe/trunk/lib/Sema/SemaStmt.cpp Sat Jan 21 12:12:07 2012 @@ -924,11 +924,17 @@ if (RI == CaseRanges.end() || EI->first < RI->first) { hasCasesNotInSwitch = true; - if (!TheDefaultStmt) - UnhandledNames.push_back(EI->second->getDeclName()); + UnhandledNames.push_back(EI->second->getDeclName()); } } + if (TheDefaultStmt) { + if (UnhandledNames.size() == 0) + Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default); + else + UnhandledNames.clear(); + } + // Produce a nice diagnostic if multiple values aren't handled. switch (UnhandledNames.size()) { case 0: break; Modified: cfe/trunk/test/Sema/switch.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch.c?rev=148640&r1=148639&r2=148640&view=diff ============================================================================== --- cfe/trunk/test/Sema/switch.c (original) +++ cfe/trunk/test/Sema/switch.c Sat Jan 21 12:12:07 2012 @@ -288,3 +288,12 @@ case 0: return; } } + +int test18() { + enum { A, B } a; + switch (a) { + case A: return 0; + case B: return 1; + default: return 2; // expected-warning {{default is unreachable as all enumeration values are accounted for}} + } +} Modified: cfe/trunk/test/Sema/warn-unreachable.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-unreachable.c?rev=148640&r1=148639&r2=148640&view=diff ============================================================================== --- cfe/trunk/test/Sema/warn-unreachable.c (original) +++ cfe/trunk/test/Sema/warn-unreachable.c Sat Jan 21 12:12:07 2012 @@ -1,4 +1,4 @@ -// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value +// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value -Wno-switch-enum-redundant-default int halt() __attribute__((noreturn)); int live(); Modified: cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp?rev=148640&r1=148639&r2=148640&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp (original) +++ cfe/trunk/test/SemaCXX/gnu-case-ranges.cpp Sat Jan 21 12:12:07 2012 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify -Wno-switch-enum-redundant-default %s enum E { one, Modified: cfe/trunk/test/SemaCXX/return-noreturn.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/return-noreturn.cpp?rev=148640&r1=148639&r2=148640&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/return-noreturn.cpp (original) +++ cfe/trunk/test/SemaCXX/return-noreturn.cpp Sat Jan 21 12:12:07 2012 @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -// RUN: %clang_cc1 %s -fsyntax-only -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-switch-enum-redundant-default +// RUN: %clang_cc1 %s -fsyntax-only -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-switch-enum-redundant-default // A destructor may be marked noreturn and should still influence the CFG. void pr6884_abort() __attribute__((noreturn)); _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
