aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDeclCXX.cpp25
-rw-r--r--test/SemaCXX/class-base-member-init.cpp21
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) { }