[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