diff options
author | Anders Carlsson <andersca@mac.com> | 2010-03-30 16:19:37 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-03-30 16:19:37 +0000 |
commit | ee11b2dd530f3fb873e108f21341626168758a45 (patch) | |
tree | ba220c2cc2fabe8663837aa51d20736be47cb208 | |
parent | 8f1a24071faabf5796eb7dc1b19be52dc1a2d324 (diff) |
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
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 25 | ||||
-rw-r--r-- | 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<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(); 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) { } |