aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-06-30 21:52:59 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-06-30 21:52:59 +0000
commit5ac3dfc24bd2d8c5c0d9955f5de33c97e6aaaadf (patch)
treea838aa2257f06afaaa9ac0421f4c7dbd2b44f590
parent6bf01d665e7a107f1dac14debf36adb56148a783 (diff)
Diagnose multiple initialization of anonymous union
fields in the ctor-initializer list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74554 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp9
-rw-r--r--test/SemaCXX/constructor-initializer.cpp8
2 files changed, 16 insertions, 1 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 546c783a62..8c3a0bf158 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -782,7 +782,14 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
for (unsigned i = 0; i < NumMemInits; i++) {
CXXBaseOrMemberInitializer *Member =
static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
- CXXBaseOrMemberInitializer *&PrevMember = Members[Member->getBaseOrMember()];
+ void *KeyToMember = Member->getBaseOrMember();
+ // For fields injected into the class via declaration of an anonymous union,
+ // use its anonymous union class declaration as the unique key.
+ if (FieldDecl *Field = Member->getMember())
+ if (Field->getDeclContext()->isRecord() &&
+ cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
+ KeyToMember = static_cast<void *>(Field->getDeclContext());
+ CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember];
if (!PrevMember) {
PrevMember = Member;
continue;
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index d8b95cec4c..7fd748b8d3 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -66,3 +66,11 @@ struct Z : S {
Z() : S(), X(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}}
};
+class U {
+ union { int a; char* p; };
+ union { int b; double d; };
+
+ U() : a(1), p(0), d(1.0) {} // expected-error {{multiple initializations given for non-static member 'p'}} \
+ // expected-note {{previous initialization is here}}
+};
+