]> granicus.if.org Git - clang/commitdiff
DR1359: A constexpr constructor does not need to initialize an empty struct or
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 9 Feb 2012 06:40:58 +0000 (06:40 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 9 Feb 2012 06:40:58 +0000 (06:40 +0000)
empty union. This still rejects anonymous member structs or unions which only
contain such empty class types, pending standard wording defining exactly what
an empty class type is.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150157 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp

index 62332b8b4aaac73a20c5af3f507279539dad85a4..8ba84fe86a50d8b82e45c2e29850cc41f899c966 100644 (file)
@@ -815,7 +815,11 @@ static void CheckConstexprCtorInitializer(Sema &SemaRef,
                                           bool &Diagnosed) {
   if (Field->isUnnamedBitfield())
     return;
-  
+
+  if (Field->isAnonymousStructOrUnion() &&
+      Field->getType()->getAsCXXRecordDecl()->isEmpty())
+    return;
+
   if (!Inits.count(Field)) {
     if (!Diagnosed) {
       SemaRef.Diag(Dcl->getLocation(), diag::err_constexpr_ctor_missing_init);
@@ -901,11 +905,14 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body,
   if (const CXXConstructorDecl *Constructor
         = dyn_cast<CXXConstructorDecl>(Dcl)) {
     const CXXRecordDecl *RD = Constructor->getParent();
-    // - every non-static data member and base class sub-object shall be
-    //   initialized;
+    // DR1359:
+    // - every non-variant non-static data member and base class sub-object
+    //   shall be initialized;
+    // - if the class is a non-empty union, or for each non-empty anonymous
+    //   union member of a non-union class, exactly one non-static data member
+    //   shall be initialized;
     if (RD->isUnion()) {
-      // DR1359: Exactly one member of a union shall be initialized.
-      if (Constructor->getNumCtorInitializers() == 0) {
+      if (Constructor->getNumCtorInitializers() == 0 && !RD->isEmpty()) {
         Diag(Dcl->getLocation(), diag::err_constexpr_union_ctor_no_init);
         return false;
       }
index abd5292ada7187ede6b132002304118853950efd..86b7ded95950fed2194c84bbdb073e5c204ed624 100644 (file)
@@ -151,6 +151,16 @@ struct AnonMembers {
   constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}}
 };
 
+union Empty {
+  constexpr Empty() {} // ok
+} constexpr empty1;
+
+struct EmptyVariant {
+  union {};
+  struct {};
+  constexpr EmptyVariant() {} // ok
+} constexpr empty2;
+
 template<typename T> using Int = int;
 template<typename T>
 struct TemplateInit {