Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -457,7 +457,6 @@ def : DiagGroup<"sign-promo">; def SignCompare : DiagGroup<"sign-compare">; def : DiagGroup<"stack-protector">; -def : DiagGroup<"switch-default">; def : DiagGroup<"synth">; def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">; def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">; @@ -536,6 +535,7 @@ def ObjCCStringFormat : DiagGroup<"cstring-format-directive">; def CoveredSwitchDefault : DiagGroup<"covered-switch-default">; def SwitchBool : DiagGroup<"switch-bool">; +def SwitchDefault : DiagGroup<"switch-default">; def SwitchEnum : DiagGroup<"switch-enum">; def Switch : DiagGroup<"switch">; def EnumCompareSwitch : DiagGroup<"enum-compare-switch">; Index: include/clang/Basic/DiagnosticIDs.h =================================================================== --- include/clang/Basic/DiagnosticIDs.h +++ include/clang/Basic/DiagnosticIDs.h @@ -36,7 +36,7 @@ DIAG_SIZE_AST = 150, DIAG_SIZE_COMMENT = 100, DIAG_SIZE_CROSSTU = 100, - DIAG_SIZE_SEMA = 3500, + DIAG_SIZE_SEMA = 3600, DIAG_SIZE_ANALYSIS = 100, DIAG_SIZE_REFACTORING = 1000, }; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8175,6 +8175,9 @@ def warn_unreachable_default : Warning< "default label in switch which covers all enumeration values">, InGroup, DefaultIgnore; +def warn_missing_default_label : Warning< + "missing default label in switch">, + InGroup, DefaultIgnore; def warn_not_in_enum : Warning<"case value not in enumerated type %0">, InGroup; def warn_not_in_enum_assignment : Warning<"integer constant not in range " Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -920,6 +920,9 @@ } } + if (!TheDefaultStmt) + Diag(SS->getSwitchLoc(), diag::warn_missing_default_label); + if (!HasDependentValue) { // If we don't have a default statement, check whether the // condition is constant. Index: test/Sema/switch-default.c =================================================================== --- test/Sema/switch-default.c +++ test/Sema/switch-default.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-default %s + +enum E { case1, case2 }; + +void warn(int x, enum E e) { + switch (x) { // expected-warning {{missing default label in switch}} + case 0: + break; + } + + switch (e) { // expected-warning {{missing default label in switch}} + case case1: + break; + case case2: + break; + } +} + +void no_warn(int x, enum E e) { + switch (x) { + case 0: + break; + default: + break; + } + + switch (e) { + case case1: + break; + case case2: + break; + default: + break; + } +} Index: test/SemaCXX/switch-default.cpp =================================================================== --- test/SemaCXX/switch-default.cpp +++ test/SemaCXX/switch-default.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-default %s + +enum E { case1, case2 }; + +void warn(int x, enum E e) { + switch (x) { // expected-warning {{missing default label in switch}} + case 0: + break; + } + + switch (e) { // expected-warning {{missing default label in switch}} + case case1: + break; + case case2: + break; + } +} + +void no_warn(int x, enum E e) { + switch (x) { + case 0: + break; + default: + break; + } + + switch (e) { + case case1: + break; + case case2: + break; + default: + break; + } +}