diff options
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 17 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp | 10 |
2 files changed, 22 insertions, 5 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 62332b8b4a..8ba84fe86a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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; } diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp index abd5292ada..86b7ded959 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp @@ -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 { |