aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-03-30 16:19:37 +0000
committerAnders Carlsson <andersca@mac.com>2010-03-30 16:19:37 +0000
commitee11b2dd530f3fb873e108f21341626168758a45 (patch)
treeba220c2cc2fabe8663837aa51d20736be47cb208
parent8f1a24071faabf5796eb7dc1b19be52dc1a2d324 (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.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) { }