Index: cfe/trunk/lib/Sema/SemaStmt.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaStmt.cpp +++ cfe/trunk/lib/Sema/SemaStmt.cpp @@ -1070,7 +1070,8 @@ const EnumType *ET = CondTypeBeforePromotion->getAs(); // If switch has default case, then ignore it. - if (!CaseListIsErroneous && !HasConstantCond && ET) { + if (!CaseListIsErroneous && !HasConstantCond && ET && + ET->getDecl()->isCompleteDefinition()) { const EnumDecl *ED = ET->getDecl(); EnumValsTy EnumVals; Index: cfe/trunk/test/SemaCXX/switch.cpp =================================================================== --- cfe/trunk/test/SemaCXX/switch.cpp +++ cfe/trunk/test/SemaCXX/switch.cpp @@ -100,3 +100,33 @@ } template void f(S); // expected-note {{instantiation of}} } + +// rdar://29230764 +namespace OpaqueEnumWarnings { + +enum Opaque : int; +enum class OpaqueClass : int; + +enum class Defined : int; +enum class Defined : int { a }; + +void test(Opaque o, OpaqueClass oc, Defined d) { + // Don't warn that case value is not present in opaque enums. + switch (o) { + case (Opaque)1: + break; + } + switch (oc) { + case (OpaqueClass)1: + break; + } + + switch (d) { + case Defined::a: + break; + case (Defined)2: // expected-warning {{case value not in enumerated type 'OpaqueEnumWarnings::Defined'}} + break; + } +} + +}