From: Richard Smith Date: Wed, 6 Jan 2016 21:54:29 +0000 (+0000) Subject: Fix half of PR26048. We don't yet diagnose the case where the anonymous union member... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c1b069d417d337d7468283f71b416d87613b00f;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256979 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index f27fb2b107..645074deaa 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3962,9 +3962,6 @@ static bool CheckAnonMemberRedeclaration(Sema &SemaRef, Sema::ForRedeclaration); if (!SemaRef.LookupName(R, S)) return false; - if (R.getAsSingle()) - 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(DC)) - if (Record->getIdentifier() && Record->getDeclName() == Name) { - Diag(NameInfo.getLoc(), diag::err_member_name_of_class) << Name; - return true; - } + CXXRecordDecl *Record = dyn_cast(DC); + while (Record && Record->isAnonymousStructOrUnion()) + Record = dyn_cast(Record->getParent()); + if (Record && Record->getIdentifier() && Record->getDeclName() == Name) { + Diag(NameInfo.getLoc(), diag::err_member_name_of_class) << Name; + return true; + } return false; } diff --git a/test/CXX/class/class.mem/p13.cpp b/test/CXX/class/class.mem/p13.cpp index 1d7b9bc815..bc01fd4d30 100644 --- a/test/CXX/class/class.mem/p13.cpp +++ b/test/CXX/class/class.mem/p13.cpp @@ -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'}} }; }; }; diff --git a/test/CXX/class/class.union/class.union.anon/p1.cpp b/test/CXX/class/class.union/class.union.anon/p1.cpp new file mode 100644 index 0000000000..7fef4c5d17 --- /dev/null +++ b/test/CXX/class/class.union/class.union.anon/p1.cpp @@ -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}} +}; diff --git a/test/CXX/class/class.union/p8.cpp b/test/CXX/class/class.union/class.union.anon/p4.cpp similarity index 100% rename from test/CXX/class/class.union/p8.cpp rename to test/CXX/class/class.union/class.union.anon/p4.cpp diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp index 3520245a03..0b654266f7 100644 --- a/test/SemaCXX/anonymous-union.cpp +++ b/test/SemaCXX/anonymous-union.cpp @@ -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}} };