forked from OSchip/llvm-project
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:
parent
4954354666
commit
0f56118c57
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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'}}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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}}
|
||||
};
|
|
@ -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}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue