Index: lib/AST/DeclBase.cpp =================================================================== --- lib/AST/DeclBase.cpp +++ lib/AST/DeclBase.cpp @@ -1700,8 +1700,15 @@ DeclContext *DeclContext::getRedeclContext() { DeclContext *Ctx = this; - // Skip through transparent contexts. - while (Ctx->isTransparentContext()) + + // In C, the redeclaration context for enumerators is the translation unit, + // so we skip through transparent contexts as well as struct/union contexts. + bool SkipRecords = getDeclKind() == Decl::Kind::Enum && + !getParentASTContext().getLangOpts().CPlusPlus; + + // Skip through contexts to get to the redeclaration context. Transparent + // contexts are always skipped. + while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext()) Ctx = Ctx->getParent(); return Ctx; } Index: test/Sema/enum.c =================================================================== --- test/Sema/enum.c +++ test/Sema/enum.c @@ -135,3 +135,26 @@ }; int makeStructNonEmpty; }; + +static int EnumRedecl; // expected-note 2 {{previous definition is here}} +struct S { + enum { + EnumRedecl = 4 // expected-error {{redefinition of 'EnumRedecl'}} + } e; +}; + +union U { + enum { + EnumRedecl = 5 // expected-error {{redefinition of 'EnumRedecl'}} + } e; +}; + +enum PR15071 { + PR15071_One // expected-note {{previous definition is here}} +}; + +struct EnumRedeclStruct { + enum { + PR15071_One // expected-error {{redefinition of enumerator 'PR15071_One'}} + } e; +};