[cfe-commits] r141549 - in /cfe/trunk: lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.cpp test/CXX/class/class.bit/p2.cpp
Douglas Gregor
dgregor at apple.com
Mon Oct 10 10:22:14 PDT 2011
Author: dgregor
Date: Mon Oct 10 12:22:13 2011
New Revision: 141549
URL: http://llvm.org/viewvc/llvm-project?rev=141549&view=rev
Log:
Per C++ [class.bit]p2, unnamed bit-fields are not members. Fixes PR10289.
Added:
cfe/trunk/test/CXX/class/class.bit/p2.cpp (with props)
Modified:
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=141549&r1=141548&r2=141549&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Oct 10 12:22:13 2011
@@ -653,6 +653,13 @@
// Handle non-static data members.
if (FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
+ // C++ [class.bit]p2:
+ // A declaration for a bit-field that omits the identifier declares an
+ // unnamed bit-field. Unnamed bit-fields are not members and cannot be
+ // initialized.
+ if (Field->isUnnamedBitfield())
+ return;
+
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class (clause 9) with [...] no
// private or protected non-static data members (clause 11).
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=141549&r1=141548&r2=141549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Oct 10 12:22:13 2011
@@ -810,6 +810,9 @@
FieldDecl *Field,
llvm::SmallSet<Decl*, 16> &Inits,
bool &Diagnosed) {
+ if (Field->isUnnamedBitfield())
+ return;
+
if (!Inits.count(Field)) {
if (!Diagnosed) {
SemaRef.Diag(Dcl->getLocation(), diag::err_constexpr_ctor_missing_init);
@@ -2816,6 +2819,13 @@
MemEnd = ClassDecl->decls_end();
Mem != MemEnd; ++Mem) {
if (FieldDecl *F = dyn_cast<FieldDecl>(*Mem)) {
+ // C++ [class.bit]p2:
+ // A declaration for a bit-field that omits the identifier declares an
+ // unnamed bit-field. Unnamed bit-fields are not members and cannot be
+ // initialized.
+ if (F->isUnnamedBitfield())
+ continue;
+
if (F->getType()->isIncompleteArrayType()) {
assert(ClassDecl->hasFlexibleArrayMember() &&
"Incomplete array type is not valid");
@@ -2956,9 +2966,13 @@
// 3. Direct fields.
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
- E = ClassDecl->field_end(); Field != E; ++Field)
+ E = ClassDecl->field_end(); Field != E; ++Field) {
+ if (Field->isUnnamedBitfield())
+ continue;
+
IdealInitKeys.push_back(GetKeyForTopLevelField(*Field));
-
+ }
+
unsigned NumIdealInits = IdealInitKeys.size();
unsigned IdealIndex = 0;
@@ -3530,7 +3544,7 @@
for (RecordDecl::field_iterator F = Record->field_begin(),
FEnd = Record->field_end();
F != FEnd; ++F) {
- if (F->hasInClassInitializer())
+ if (F->hasInClassInitializer() || F->isUnnamedBitfield())
continue;
if (F->getType()->isReferenceType() ||
@@ -4202,7 +4216,7 @@
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
FE = RD->field_end();
FI != FE; ++FI) {
- if (FI->isInvalidDecl())
+ if (FI->isInvalidDecl() || FI->isUnnamedBitfield())
continue;
QualType FieldType = Context.getBaseElementType(FI->getType());
@@ -4402,6 +4416,9 @@
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
FE = RD->field_end();
FI != FE; ++FI) {
+ if (FI->isUnnamedBitfield())
+ continue;
+
QualType FieldType = Context.getBaseElementType(FI->getType());
// -- for a copy constructor, a non-static data member of rvalue reference
@@ -4539,6 +4556,9 @@
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
FE = RD->field_end();
FI != FE; ++FI) {
+ if (FI->isUnnamedBitfield())
+ continue;
+
QualType FieldType = Context.getBaseElementType(FI->getType());
// -- a non-static data member of reference type
@@ -4695,6 +4715,9 @@
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
FE = RD->field_end();
FI != FE; ++FI) {
+ if (FI->isUnnamedBitfield())
+ continue;
+
QualType FieldType = Context.getBaseElementType(FI->getType());
if (CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl()) {
@@ -4815,6 +4838,9 @@
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
FE = RD->field_end();
FI != FE; ++FI) {
+ if (FI->isUnnamedBitfield())
+ continue;
+
QualType FieldType = Context.getBaseElementType(FI->getType());
// -- a non-static data member of reference type
@@ -7922,6 +7948,9 @@
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
FieldEnd = ClassDecl->field_end();
Field != FieldEnd; ++Field) {
+ if (Field->isUnnamedBitfield())
+ continue;
+
// Check for members of reference type; we can't copy those.
if (Field->getType()->isReferenceType()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
@@ -8340,6 +8369,9 @@
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
FieldEnd = ClassDecl->field_end();
Field != FieldEnd; ++Field) {
+ if (Field->isUnnamedBitfield())
+ continue;
+
// Check for members of reference type; we can't move those.
if (Field->getType()->isReferenceType()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=141549&r1=141548&r2=141549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Oct 10 12:22:13 2011
@@ -490,7 +490,7 @@
Field = structDecl->field_begin(),
FieldEnd = structDecl->field_end();
Field != FieldEnd; ++Field) {
- if ((*Field)->getIdentifier() || !(*Field)->isBitField())
+ if (!Field->isUnnamedBitfield())
++InitializableMembers;
}
if (structDecl->isUnion())
Added: cfe/trunk/test/CXX/class/class.bit/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.bit/p2.cpp?rev=141549&view=auto
==============================================================================
--- cfe/trunk/test/CXX/class/class.bit/p2.cpp (added)
+++ cfe/trunk/test/CXX/class/class.bit/p2.cpp Mon Oct 10 12:22:13 2011
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+struct A {
+private:
+ int : 0;
+};
+
+A a = { };
+A a2 = { 1 }; // expected-error{{excess elements in struct initializer}}
+
+struct B {
+ const int : 0;
+};
+
+B b;
+
+void testB() {
+ B b2(b);
+ B b3(static_cast<B&&>(b2));
+ b = b;
+ b = static_cast<B&&>(b);
+}
Propchange: cfe/trunk/test/CXX/class/class.bit/p2.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CXX/class/class.bit/p2.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CXX/class/class.bit/p2.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list