]> granicus.if.org Git - clang/commitdiff
Diagnose multiple initialization of anonymous union
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 30 Jun 2009 21:52:59 +0000 (21:52 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 30 Jun 2009 21:52:59 +0000 (21:52 +0000)
fields in the ctor-initializer list.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74554 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/constructor-initializer.cpp

index 546c783a623703e0e6b88f73e08b1d7abda982db..8c3a0bf1584123350aa07945f645303e4925c12a 100644 (file)
@@ -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;
index d8b95cec4cd9789d0e8e2d3e5fe05e171c6b1170..7fd748b8d34b2cfffc5e08dbf1ba4ef1cc626853 100644 (file)
@@ -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}}
+};
+