[clang] 997b072 - C++ DR2394: Const-default-constructible for members.

James Y Knight via cfe-commits cfe-commits at lists.llvm.org
Wed May 25 11:57:53 PDT 2022


Author: James Y Knight
Date: 2022-05-25T14:20:11-04:00
New Revision: 997b072e10d2be09c0e1a5bf4d6b92e2da3b8cc6

URL: https://github.com/llvm/llvm-project/commit/997b072e10d2be09c0e1a5bf4d6b92e2da3b8cc6
DIFF: https://github.com/llvm/llvm-project/commit/997b072e10d2be09c0e1a5bf4d6b92e2da3b8cc6.diff

LOG: C++ DR2394: Const-default-constructible for members.

Const class members may be initialized with a defaulted default
constructor under the same conditions it would be allowed for a const
object elsewhere.

Differential Revision: https://reviews.llvm.org/D126170

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/test/CXX/drs/dr23xx.cpp
    clang/test/CXX/special/class.ctor/p5-0x.cpp
    clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
    clang/www/cxx_dr_status.html

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a457a8fb2efe4..c34d29c8762d4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -155,6 +155,9 @@ Bug Fixes
   a coroutine will no longer generate a call to a global allocation function
   with the signature (std::size_t, p0, ..., pn).
   This fixes Issue `Issue 54881 <https://github.com/llvm/llvm-project/issues/54881>`_.
+- Implement `CWG 2394 <https://wg21.link/cwg2394>`_: Const class members
+  may be initialized with a defaulted default constructor under the same
+  conditions it would be allowed for a const object elsewhere.
 
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index a16fe0b1b72a4..c470a46f58477 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9213,13 +9213,12 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
           << !!ICI << MD->getParent() << FD << FieldType << /*Reference*/0;
       return true;
     }
-    // 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.
+    // C++11 [class.ctor]p5 (modified by DR2394): any non-variant non-static
+    // data member of const-qualified type (or array thereof) with no
+    // brace-or-equal-initializer is not const-default-constructible.
     if (!inUnion() && FieldType.isConstQualified() &&
         !FD->hasInClassInitializer() &&
-        (!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor())) {
+        (!FieldRecord || !FieldRecord->allowConstDefaultInit())) {
       if (Diagnose)
         S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field)
           << !!ICI << MD->getParent() << FD << FD->getType() << /*Const*/1;

diff  --git a/clang/test/CXX/drs/dr23xx.cpp b/clang/test/CXX/drs/dr23xx.cpp
index a7ff2a5813ed0..8d6b4a5dc16ea 100644
--- a/clang/test/CXX/drs/dr23xx.cpp
+++ b/clang/test/CXX/drs/dr23xx.cpp
@@ -158,3 +158,14 @@ void g() {
 }
 } //namespace dr2303
 #endif
+
+namespace dr2394 { // dr2394: 15
+
+struct A {};
+const A a;
+
+// Now allowed to default-init B.
+struct B { const A a; };
+B b;
+
+}

diff  --git a/clang/test/CXX/special/class.ctor/p5-0x.cpp b/clang/test/CXX/special/class.ctor/p5-0x.cpp
index 67f0d2a935744..c433df64a7cf4 100644
--- a/clang/test/CXX/special/class.ctor/p5-0x.cpp
+++ b/clang/test/CXX/special/class.ctor/p5-0x.cpp
@@ -2,6 +2,8 @@
 
 struct DefaultedDefCtor1 {};
 struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; };
+struct DefaultedDefCtorUninitialized1 { int x; };
+struct DefaultedDefCtorUninitialized2 { int x; DefaultedDefCtorUninitialized2() = default; };
 struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); }; // expected-note {{explicitly marked deleted here}}
 class PrivateDefCtor { PrivateDefCtor() = default; public: PrivateDefCtor(int); };
 struct DeletedDtor { ~DeletedDtor() = delete; }; // expected-note 4{{explicitly marked deleted here}}
@@ -51,21 +53,20 @@ class NotDeleted2d { int &&a = 0; }; // expected-error {{reference member 'a' bi
 NotDeleted2d nd2d; // expected-note {{first required here}}
 
 // - 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,
+// thereof) with no brace-or-equal-initializer is not const-default-constructible
 class Deleted3a { const int a; }; // expected-note {{because field 'a' of const-qualified type 'const int' would not be initialized}} \
                                      expected-warning {{does not declare any constructor}} \
                                      expected-note {{will never be initialized}}
 Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
-class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1[42]' would not be initialized}}
+class Deleted3b { const DefaultedDefCtorUninitialized1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtorUninitialized1[42]' would not be initialized}}
 Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
-class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}}
+class Deleted3c { const DefaultedDefCtorUninitialized2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtorUninitialized2' would not be initialized}}
 Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
 class NotDeleted3a { const int a = 0; };
 NotDeleted3a nd3a;
-class NotDeleted3b { const DefaultedDefCtor1 a[42] = {}; };
+class NotDeleted3b { const DefaultedDefCtorUninitialized1 a[42] = {}; };
 NotDeleted3b nd3b;
-class NotDeleted3c { const DefaultedDefCtor2 a = DefaultedDefCtor2(); };
+class NotDeleted3c { const DefaultedDefCtorUninitialized2 a = DefaultedDefCtorUninitialized2(); };
 NotDeleted3c nd3c;
 union NotDeleted3d { const int a; int b; };
 NotDeleted3d nd3d;
@@ -75,6 +76,10 @@ union NotDeleted3f { const DefaultedDefCtor2 a; int b; };
 NotDeleted3f nd3f;
 struct NotDeleted3g { union { const int a; int b; }; };
 NotDeleted3g nd3g;
+struct NotDeleted3h { const DefaultedDefCtor1 a[42]; };
+NotDeleted3h nd3h;
+struct NotDeleted3i { const DefaultedDefCtor2 a; };
+NotDeleted3i nd3i;
 
 // - X is a union and all of its variant members are of const-qualified type (or
 // array thereof),

diff  --git a/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
index feb483546c3eb..f8a40f97c9791 100644
--- a/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
+++ b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -48,8 +48,12 @@ struct good : non_trivial {
 };
 good g;
 
+struct bad_const_inner {
+  int x;
+};
+
 struct bad_const {
-  const good g; // expected-note {{field 'g' of const-qualified type 'const good' would not be initialized}}
+  const bad_const_inner g; // expected-note {{field 'g' of const-qualified type 'const bad_const_inner' would not be initialized}}
 };
 bad_const bc; // expected-error {{call to implicitly-deleted default constructor}}
 

diff  --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index e193d37c09598..b9a38150063bc 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -14178,7 +14178,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td><a href="https://wg21.link/cwg2394">2394</a></td>
     <td>CD5</td>
     <td>Const-default-constructible for members</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="unreleased" align="center">Clang 15</td>
   </tr>
   <tr class="open" id="2395">
     <td><a href="https://wg21.link/cwg2395">2395</a></td>


        


More information about the cfe-commits mailing list