From ee11b2dd530f3fb873e108f21341626168758a45 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 30 Mar 2010 16:19:37 +0000 Subject: [PATCH] Fix a bug where we would incorrectly report an error about initializing two fields in an anonymous struct. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99891 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 25 ++++++++++++++----------- test/SemaCXX/class-base-member-init.cpp | 21 +++++++++++++++------ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3509cb5e86..6a2a037e9e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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(Field->getDeclContext()); - if (RD->isAnonymousStructOrUnion()) - return static_cast(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(RD); return static_cast(Field); } @@ -1719,7 +1720,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, } if (!Constructor->isDependentContext()) { - llvm::DenseMapMembers; + llvm::DenseMap 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(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(CDtorDecl.getAs())) - 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(); diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp index 1c6e79012e..0821c34b02 100644 --- a/test/SemaCXX/class-base-member-init.cpp +++ b/test/SemaCXX/class-base-member-init.cpp @@ -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) { } -- 2.40.0