[cfe-commits] r118381 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/CXX/class/class.union/p1.cpp test/SemaCXX/member-expr-anonymous-union.cpp

Anders Carlsson andersca at mac.com
Sun Nov 7 11:13:55 PST 2010


Author: andersca
Date: Sun Nov  7 13:13:55 2010
New Revision: 118381

URL: http://llvm.org/viewvc/llvm-project?rev=118381&view=rev
Log:
A union cannot contain static data members or data members of reference type.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/class/class.union/p1.cpp
    cfe/trunk/test/SemaCXX/member-expr-anonymous-union.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=118381&r1=118380&r2=118381&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sun Nov  7 13:13:55 2010
@@ -341,7 +341,7 @@
     
     /// \brief Whether we have already declared a destructor within the class.
     bool DeclaredDestructor : 1;
-    
+
     /// NumBases - The number of base class specifiers in Bases.
     unsigned NumBases;
     

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=118381&r1=118380&r2=118381&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Nov  7 13:13:55 2010
@@ -674,6 +674,10 @@
 def note_nontrivial_user_defined : Note<
   "because type %0 has a user-declared %select{constructor|copy constructor|"
   "copy assignment operator|destructor}1">;
+def err_static_data_member_not_allowed_in_union_or_anon_struct : Error<
+  "static data member %0 not allowed in %select{anonymous struct|union}1">; 
+def err_union_member_of_reference_type : Error<
+  "union member %0 has reference type %1">;
 
 def err_different_return_type_for_overriding_virtual_function : Error<
   "virtual function %0 has a different return type (%1) than the "

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=118381&r1=118380&r2=118381&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Nov  7 13:13:55 2010
@@ -2788,6 +2788,15 @@
         Diag(D.getIdentifierLoc(),
              diag::err_static_data_member_not_allowed_in_local_class)
           << Name << RD->getDeclName();
+
+      // C++ [class.union]p1: If a union contains a static data member,
+      // the program is ill-formed.
+      //
+      // We also disallow static data members in anonymous structs.
+      if (CurContext->isRecord() && (RD->isUnion() || !RD->getDeclName()))
+        Diag(D.getIdentifierLoc(),
+             diag::err_static_data_member_not_allowed_in_union_or_anon_struct)
+          << Name << RD->isUnion();
     }
   }
 
@@ -6444,17 +6453,27 @@
   }
 
   if (!InvalidDecl && getLangOptions().CPlusPlus) {
-    if (const RecordType *RT = EltTy->getAs<RecordType>()) {
-      CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
-      if (RDecl->getDefinition()) {
-        // C++ 9.5p1: An object of a class with a non-trivial
-        // constructor, a non-trivial copy constructor, a non-trivial
-        // destructor, or a non-trivial copy assignment operator
-        // cannot be a member of a union, nor can an array of such
-        // objects.
-        // TODO: C++0x alters this restriction significantly.
-        if (Record->isUnion() && CheckNontrivialField(NewFD))
-          NewFD->setInvalidDecl();
+    if (Record->isUnion()) {
+      if (const RecordType *RT = EltTy->getAs<RecordType>()) {
+        CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
+        if (RDecl->getDefinition()) {
+          // C++ [class.union]p1: An object of a class with a non-trivial
+          // constructor, a non-trivial copy constructor, a non-trivial
+          // destructor, or a non-trivial copy assignment operator
+          // cannot be a member of a union, nor can an array of such
+          // objects.
+          // TODO: C++0x alters this restriction significantly.
+          if (CheckNontrivialField(NewFD))
+            NewFD->setInvalidDecl();
+        }
+      }
+
+      // C++ [class.union]p1: If a union contains a member of reference type,
+      // the program is ill-formed.
+      if (EltTy->isReferenceType()) {
+        Diag(NewFD->getLocation(), diag::err_union_member_of_reference_type)
+          << NewFD->getDeclName() << EltTy;
+        NewFD->setInvalidDecl();
       }
     }
   }

Modified: cfe/trunk/test/CXX/class/class.union/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.union/p1.cpp?rev=118381&r1=118380&r2=118381&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.union/p1.cpp (original)
+++ cfe/trunk/test/CXX/class/class.union/p1.cpp Sun Nov  7 13:13:55 2010
@@ -90,6 +90,14 @@
   } m7;
 };
 
+union U4 {
+  static int i1; // expected-error {{static data member 'i1' not allowed in union}}
+};
+
+union U5 {
+  int& i1; // expected-error {{union member 'i1' has reference type 'int &'}}
+};
+
 template <class A, class B> struct Either {
   bool tag;
   union {

Modified: cfe/trunk/test/SemaCXX/member-expr-anonymous-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-expr-anonymous-union.cpp?rev=118381&r1=118380&r2=118381&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/member-expr-anonymous-union.cpp (original)
+++ cfe/trunk/test/SemaCXX/member-expr-anonymous-union.cpp Sun Nov  7 13:13:55 2010
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 %s -fsyntax-only -verify
 // PR5543
 
-struct A { int x; union { int* y; float& z; }; }; struct B : A {int a;};
+struct A { int x; union { int* y; float* z; }; }; struct B : A {int a;};
 int* a(B* x) { return x->y; }
 
 struct x { union { int y; }; }; x y; template <int X> int f() { return X+y.y; }





More information about the cfe-commits mailing list