Fix half of PR26048. We don't yet diagnose the case where the anonymous union member is declared first and the tag name is declared second.

llvm-svn: 256979
This commit is contained in:
Richard Smith 2016-01-06 21:54:29 +00:00
parent 4954354666
commit 0f56118c57
5 changed files with 37 additions and 12 deletions

View File

@ -3962,9 +3962,6 @@ static bool CheckAnonMemberRedeclaration(Sema &SemaRef,
Sema::ForRedeclaration);
if (!SemaRef.LookupName(R, S)) return false;
if (R.getAsSingle<TagDecl>())
return false;
// Pick a representative declaration.
NamedDecl *PrevDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
assert(PrevDecl && "Expected a non-null Decl");
@ -4675,11 +4672,13 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,
DeclarationNameInfo NameInfo) {
DeclarationName Name = NameInfo.getName();
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
if (Record->getIdentifier() && Record->getDeclName() == Name) {
Diag(NameInfo.getLoc(), diag::err_member_name_of_class) << Name;
return true;
}
CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC);
while (Record && Record->isAnonymousStructOrUnion())
Record = dyn_cast<CXXRecordDecl>(Record->getParent());
if (Record && Record->getIdentifier() && Record->getDeclName() == Name) {
Diag(NameInfo.getLoc(), diag::err_member_name_of_class) << Name;
return true;
}
return false;
}

View File

@ -58,12 +58,12 @@ struct X3a {
};
// - every member of every anonymous union that is a member of class T.
struct X4 {
struct X4 { // expected-note{{previous}}
union {
int X;
union {
float Y;
unsigned X4; // expected-error{{member 'X4' has the same name as its class}}
unsigned X4; // expected-error{{redeclares 'X4'}}
};
};
};

View File

@ -0,0 +1,26 @@
// RUN: %clang_cc1 -verify %s
struct X {
int a; // expected-note {{previous}}
void b(); // expected-note {{previous}}
struct c; // expected-note {{previous}}
typedef int d; // expected-note {{previous}}
union {
int a; // expected-error {{member of anonymous union redeclares}}
int b; // expected-error {{member of anonymous union redeclares}}
int c; // expected-error {{member of anonymous union redeclares}}
int d; // expected-error {{member of anonymous union redeclares}}
int e; // expected-note {{previous}}
int f; // expected-note {{previous}}
int g;
int h; // expected-note {{previous}}
};
int e; // expected-error {{duplicate member}}
void f(); // expected-error {{redefinition}}
// FIXME: This is ill-formed, even though one name is a tag and the other is
// an anonymous union member. Reject this.
struct g;
typedef int h; // expected-error {{redefinition}}
};

View File

@ -62,11 +62,11 @@ void test_unqual_references(X x, const X xc) {
struct Redecl {
int x; // expected-note{{previous declaration is here}}
class y { };
class y { }; // expected-note{{previous declaration is here}}
union {
int x; // expected-error{{member of anonymous union redeclares 'x'}}
float y;
float y; // expected-error{{member of anonymous union redeclares 'y'}}
double z; // expected-note{{previous declaration is here}}
double zz; // expected-note{{previous definition is here}}
};