[cfe-commits] r151516 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/CXX/special/class.ctor/p5-0x.cpp

Richard Smith richard-llvm at metafoo.co.uk
Sun Feb 26 22:07:26 PST 2012


Author: rsmith
Date: Mon Feb 27 00:07:25 2012
New Revision: 151516

URL: http://llvm.org/viewvc/llvm-project?rev=151516&view=rev
Log:
Ensure that we delete default constructors in the right cases. Don't delete the
default constructor of a union if it has a const member with no user-provided
default constructor.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/special/class.ctor/p5-0x.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=151516&r1=151515&r2=151516&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Feb 27 00:07:25 2012
@@ -4485,6 +4485,15 @@
 
     if (inUnion() && !FieldType.isConstQualified())
       AllFieldsAreConst = false;
+
+    // C++11 [class.ctor]p5: any non-variant non-static data member of
+    // const-qualified type (or array thereof) with no
+    // brace-or-equal-initializer does not have a user-provided default
+    // constructor.
+    if (!inUnion() && FieldType.isConstQualified() &&
+        !FD->hasInClassInitializer() &&
+        (!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor()))
+      return true;
   } else if (CSM == Sema::CXXCopyConstructor) {
     // For a copy constructor, data members must not be of rvalue reference
     // type.
@@ -4497,13 +4506,6 @@
   }
 
   if (FieldRecord) {
-    // For a default constructor, a const member must have a user-provided
-    // default constructor or else be explicitly initialized.
-    if (CSM == Sema::CXXDefaultConstructor && FieldType.isConstQualified() &&
-        !FD->hasInClassInitializer() &&
-        !FieldRecord->hasUserProvidedDefaultConstructor())
-      return true;
-
     // Some additional restrictions exist on the variant members.
     if (!inUnion() && FieldRecord->isUnion() &&
         FieldRecord->isAnonymousStructOrUnion()) {
@@ -4592,10 +4594,6 @@
           return true;
       }
     }
-  } else if (CSM == Sema::CXXDefaultConstructor && !inUnion() &&
-             FieldType.isConstQualified() && !FD->hasInClassInitializer()) {
-    // We can't initialize a const member of non-class type to any value.
-    return true;
   } else if (IsAssignment && FieldType.isConstQualified()) {
     // C++11 [class.copy]p23:
     // -- a non-static data member of const non-class type (or array thereof)

Modified: cfe/trunk/test/CXX/special/class.ctor/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.ctor/p5-0x.cpp?rev=151516&r1=151515&r2=151516&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.ctor/p5-0x.cpp (original)
+++ cfe/trunk/test/CXX/special/class.ctor/p5-0x.cpp Mon Feb 27 00:07:25 2012
@@ -35,10 +35,16 @@
   int &a; 
 }; 
 Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}}
+struct Deleted2b { // expected-note {{here}}
+  int &&b;
+};
+Deleted2b d2b; // expected-error {{deleted default constructor}}
 class NotDeleted2a { int &a = n; };
 NotDeleted2a nd2a;
 class NotDeleted2b { int &a = error; }; // expected-error {{undeclared identifier}}
 NotDeleted2b nd2b;
+class NotDeleted2c { int &&a = 0; };
+NotDeleted2c nd2c;
 
 // - any non-variant non-static data member of const qualified type (or array
 // thereof) with no brace-or-equal-initializer does not have a user-provided
@@ -59,27 +65,26 @@
 NotDeleted3c nd3c;
 union NotDeleted3d { const int a; int b; };
 NotDeleted3d nd3d;
-// FIXME: this class should not have a deleted default constructor.
-union NotDeleted3e { const DefaultedDefCtor1 a[42]; int b; }; // unexpected-note {{here}}
-NotDeleted3e nd3e; // unexpected-error {{implicitly-deleted default constructor}}
-// FIXME: clang implements the pre-FDIS rule, under which DefaultedDefCtor2 is
-// non-trivial.
-union NotDeleted3f { const DefaultedDefCtor2 a; int b; }; // unexpected-note {{here}}
-NotDeleted3f nd3f; // unexpected-error {{implicitly-deleted default constructor}}
+union NotDeleted3e { const DefaultedDefCtor1 a[42]; int b; };
+NotDeleted3e nd3e;
+union NotDeleted3f { const DefaultedDefCtor2 a; int b; };
+NotDeleted3f nd3f;
+struct NotDeleted3g { union { const int a; int b; }; };
+NotDeleted3g nd3g;
 
 // - X is a union and all of its variant members are of const-qualified type (or
 // array thereof),
 union Deleted4a { const int a; const int b; const UserProvidedDefCtor c; }; // expected-note {{here}}
 Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
-union Deleted4b { const int a; int b; };
-Deleted4b d4b;
+union NotDeleted4a { const int a; int b; };
+NotDeleted4a nd4a;
 
 // - X is a non-union class and all members of any anonymous union member are of
 // const-qualified type (or array thereof),
 struct Deleted5a { union { const int a; }; union { int b; }; }; // expected-note {{here}}
 Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted5b { union { const int a; int b; }; union { const int c; int d; }; };
-Deleted5b d5b;
+struct NotDeleted5a { union { const int a; int b; }; union { const int c; int d; }; };
+NotDeleted5a nd5a;
 
 // - any direct or virtual base class, or non-static data member with no
 // brace-or-equal-initializer, has class type M (or array thereof) and either





More information about the cfe-commits mailing list