[PATCH] D52384: [Sema] Fix redeclaration contexts for enumerators in C
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 21 17:18:46 PDT 2018
aaron.ballman created this revision.
aaron.ballman added reviewers: rsmith, dblaikie.
In C, enumerators are not hoisted into, say, a struct decl context when the enumeration is declared inside of a struct. Instead, the enumerators are hoisted into the translation unit decl context. This patch fixes `getRedeclContext()` to skip records as well as transparent contexts when the original context is an enumeration. This allows us to catch enumerator redeclarations as well as silent name hiding + miscompiles.
This patch address PR15071.
https://reviews.llvm.org/D52384
Files:
lib/AST/DeclBase.cpp
test/Sema/enum.c
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;
+};
Index: lib/AST/DeclBase.cpp
===================================================================
--- lib/AST/DeclBase.cpp
+++ lib/AST/DeclBase.cpp
@@ -1700,8 +1700,16 @@
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->isTransparentContext() || Ctx->isRecord()
+ : Ctx->isTransparentContext())
Ctx = Ctx->getParent();
return Ctx;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52384.166581.patch
Type: text/x-patch
Size: 1643 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180922/27793438/attachment.bin>
More information about the cfe-commits
mailing list