]> granicus.if.org Git - clang/commitdiff
Fix a bug where we would incorrectly report an error about initializing two fields...
authorAnders Carlsson <andersca@mac.com>
Tue, 30 Mar 2010 16:19:37 +0000 (16:19 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 30 Mar 2010 16:19:37 +0000 (16:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99891 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/class-base-member-init.cpp

index 3509cb5e8643d2001f4a9e830afcfd0f2695b1e5..6a2a037e9e9ef1ad8b54b41eb7a6ea4540d6e2bd 100644 (file)
@@ -1691,11 +1691,12 @@ static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member,
   // in AnonUnionMember field.
   if (MemberMaybeAnon && Field->isAnonymousStructOrUnion())
     Field = Member->getAnonUnionMember();
-  if (Field->getDeclContext()->isRecord()) {
-    RecordDecl *RD = cast<RecordDecl>(Field->getDeclContext());
-    if (RD->isAnonymousStructOrUnion())
-      return static_cast<void *>(RD);
-  }
+  
+  // If the field is a member of an anonymous union, we use record decl of the
+  // union as the key.
+  RecordDecl *RD = Field->getParent();
+  if (RD->isAnonymousStructOrUnion() && RD->isUnion())
+    return static_cast<void *>(RD);
 
   return static_cast<void *>(Field);
 }
@@ -1719,7 +1720,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
   }
 
   if (!Constructor->isDependentContext()) {
-    llvm::DenseMap<void*, CXXBaseOrMemberInitializer *>Members;
+    llvm::DenseMap<void*, CXXBaseOrMemberInitializer *> Members;
     bool err = false;
     for (unsigned i = 0; i < NumMemInits; i++) {
       CXXBaseOrMemberInitializer *Member =
@@ -1754,7 +1755,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
 
   SetBaseOrMemberInitializers(Constructor,
                       reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits),
-                      NumMemInits, false, AnyErrors);
+                      NumMemInits, /*IsImplicitConstructor=*/false, AnyErrors);
 
   if (Constructor->isDependentContext())
     return;
@@ -1929,11 +1930,11 @@ void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
   if (!CDtorDecl)
     return;
 
-  AdjustDeclIfTemplate(CDtorDecl);
-
   if (CXXConstructorDecl *Constructor
       = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))
-    SetBaseOrMemberInitializers(Constructor, 0, 0, false, false);
+    SetBaseOrMemberInitializers(Constructor, 0, 0, 
+                                /*IsImplicitConstructor=*/false,
+                                /*AnyErrors=*/false);
 }
 
 bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
@@ -3781,7 +3782,9 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
 
   DeclContext *PreviousContext = CurContext;
   CurContext = Constructor;
-  if (SetBaseOrMemberInitializers(Constructor, 0, 0, true, false)) {
+  if (SetBaseOrMemberInitializers(Constructor, 0, 0, 
+                                  /*IsImplicitConstructor=*/true, 
+                                  /*AnyErrors=*/false)) {
     Diag(CurrentLocation, diag::note_member_synthesized_at) 
       << CXXDefaultConstructor << Context.getTagDeclType(ClassDecl);
     Constructor->setInvalidDecl();
index 1c6e79012ea511215088ebb147bd3fdb7c315afd..0821c34b02c359e34a9d79545e2049c3688e0229 100644 (file)
@@ -6,14 +6,23 @@ public:
 };
 
 struct D : S {
-  D() : b1(0), b2(1), b1(0), S(), S() {} // expected-error {{multiple initializations given for non-static member 'b1'}} \
-                                         // expected-note {{previous initialization is here}}                  \
-                                         // expected-error {{multiple initializations given for base 'S'}} \
-                                         // expected-note {{previous initialization is here}}
-
+  D() : 
+    b1(0), // expected-note {{previous initialization is here}}
+    b2(1),
+    b1(0), // expected-error {{multiple initializations given for non-static member 'b1'}}
+    S(),   // expected-note {{previous initialization is here}}
+    S()    // expected-error {{multiple initializations given for base 'S'}}
+    {}
   int b1;
   int b2;
-
 };
 
+struct A {
+  struct {
+    int a;
+    int b; 
+  };
+  A();
+};
 
+A::A() : a(10), b(20) { }