Re: r256979 - 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.

2016-01-06 Thread Adrian Prantl via cfe-commits

> On Jan 6, 2016, at 1:54 PM, Richard Smith via cfe-commits 
>  wrote:
> 
> Author: rsmith
> Date: Wed Jan  6 15:54:29 2016
> New Revision: 256979
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=256979=rev
> Log:
> 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.
> 

Thanks!

-- adrian

> Added:
>cfe/trunk/test/CXX/class/class.union/class.union.anon/
>cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp
>cfe/trunk/test/CXX/class/class.union/class.union.anon/p4.cpp
>  - copied unchanged from r256599, 
> cfe/trunk/test/CXX/class/class.union/p8.cpp
> Removed:
>cfe/trunk/test/CXX/class/class.union/p8.cpp
> Modified:
>cfe/trunk/lib/Sema/SemaDecl.cpp
>cfe/trunk/test/CXX/class/class.mem/p13.cpp
>cfe/trunk/test/SemaCXX/anonymous-union.cpp
> 
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=256979=256978=256979=diff
> ==
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jan  6 15:54:29 2016
> @@ -3962,9 +3962,6 @@ static bool CheckAnonMemberRedeclaration
>  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(DeclC
>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;
> }
> 
> Modified: cfe/trunk/test/CXX/class/class.mem/p13.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mem/p13.cpp?rev=256979=256978=256979=diff
> ==
> --- cfe/trunk/test/CXX/class/class.mem/p13.cpp (original)
> +++ cfe/trunk/test/CXX/class/class.mem/p13.cpp Wed Jan  6 15:54:29 2016
> @@ -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'}}
> };
>   };
> };
> 
> Added: cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp?rev=256979=auto
> ==
> --- cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp (added)
> +++ cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp Wed Jan  6 
> 15:54:29 2016
> @@ -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}}
> +};
> 
> Removed: cfe/trunk/test/CXX/class/class.union/p8.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.union/p8.cpp?rev=256978=auto
> ==
> --- cfe/trunk/test/CXX/class/class.union/p8.cpp (original)
> +++ 

r256979 - 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.

2016-01-06 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Wed Jan  6 15:54:29 2016
New Revision: 256979

URL: http://llvm.org/viewvc/llvm-project?rev=256979=rev
Log:
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.

Added:
cfe/trunk/test/CXX/class/class.union/class.union.anon/
cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp
cfe/trunk/test/CXX/class/class.union/class.union.anon/p4.cpp
  - copied unchanged from r256599, 
cfe/trunk/test/CXX/class/class.union/p8.cpp
Removed:
cfe/trunk/test/CXX/class/class.union/p8.cpp
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/CXX/class/class.mem/p13.cpp
cfe/trunk/test/SemaCXX/anonymous-union.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=256979=256978=256979=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jan  6 15:54:29 2016
@@ -3962,9 +3962,6 @@ static bool CheckAnonMemberRedeclaration
  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(DeclC
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;
 }

Modified: cfe/trunk/test/CXX/class/class.mem/p13.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mem/p13.cpp?rev=256979=256978=256979=diff
==
--- cfe/trunk/test/CXX/class/class.mem/p13.cpp (original)
+++ cfe/trunk/test/CXX/class/class.mem/p13.cpp Wed Jan  6 15:54:29 2016
@@ -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'}}
 };
   };
 };

Added: cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp?rev=256979=auto
==
--- cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp (added)
+++ cfe/trunk/test/CXX/class/class.union/class.union.anon/p1.cpp Wed Jan  6 
15:54:29 2016
@@ -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}}
+};

Removed: cfe/trunk/test/CXX/class/class.union/p8.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.union/p8.cpp?rev=256978=auto
==
--- cfe/trunk/test/CXX/class/class.union/p8.cpp (original)
+++ cfe/trunk/test/CXX/class/class.union/p8.cpp (removed)
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s
-
-union U {
-  int x = 0; // expected-note {{previous initialization is here}}
-  union {};
-  union {
-int z;
-int y = 1; // expected-error {{initializing multiple members of union}}
-  };
-};

Modified: