]> granicus.if.org Git - clang/commitdiff
Fix half of PR26048. We don't yet diagnose the case where the anonymous union member...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 6 Jan 2016 21:54:29 +0000 (21:54 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 6 Jan 2016 21:54:29 +0000 (21:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256979 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/CXX/class/class.mem/p13.cpp
test/CXX/class/class.union/class.union.anon/p1.cpp [new file with mode: 0644]
test/CXX/class/class.union/class.union.anon/p4.cpp [moved from test/CXX/class/class.union/p8.cpp with 100% similarity]
test/SemaCXX/anonymous-union.cpp

index f27fb2b1071263b7ffaeca3d50618a65b4b82516..645074deaa0eccca298ed777cda8784277e222f1 100644 (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;
 }
index 1d7b9bc81551054db526993aa240cf48a13a5de0..bc01fd4d30c5698886ddafb52a5be2b978fb86c3 100644 (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'}}
     };
   };
 };
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 (file)
index 0000000..7fef4c5
--- /dev/null
@@ -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}}
+};
index 3520245a03a8548eca351dadddd3204cf679a06b..0b654266f75f788fea27cc55b2d3def1ba8c454b 100644 (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}}
   };