diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-11-07 22:16:17 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-11-07 22:16:17 +0000 |
commit | 66f85713bd0d22f867efa8e9fb0037befdd6b151 (patch) | |
tree | c0d06e5bda333ee32210eabdfac012b0e1554f0d /lib/Sema/SemaDecl.cpp | |
parent | 45fa560c72441069d9e4eb1e66efd87349caa552 (diff) |
constexpr: static data members declared constexpr are required to have an
initializer; all other constexpr variables are merely required to be
initialized. In particular, a user-provided constexpr default constructor can be
used for such initialization.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144028 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 43 |
1 files changed, 17 insertions, 26 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d71cd5f7d5..8419cbebc4 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6191,17 +6191,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (!VDecl->isInvalidDecl()) checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init); - if (VDecl->isConstexpr() && !VDecl->isInvalidDecl() && - !VDecl->getType()->isDependentType() && - !Init->isTypeDependent() && !Init->isValueDependent() && - !Init->isConstantInitializer(Context, - VDecl->getType()->isReferenceType())) { - // FIXME: Improve this diagnostic to explain why the initializer is not - // a constant expression. - Diag(VDecl->getLocation(), diag::err_constexpr_var_requires_const_init) - << VDecl << Init->getSourceRange(); - } - Init = MaybeCreateExprWithCleanups(Init); // Attach the initializer to the decl. VDecl->setInit(Init); @@ -6266,16 +6255,12 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, return; } - // C++0x [dcl.constexpr]p9: An object or reference declared constexpr must - // have an initializer. // C++0x [class.static.data]p3: A static data member can be declared with // the constexpr specifier; if so, its declaration shall specify // a brace-or-equal-initializer. - // - // A static data member's definition may inherit an initializer from an - // in-class declaration. - if (Var->isConstexpr() && !Var->getAnyInitializer()) { - Diag(Var->getLocation(), diag::err_constexpr_var_requires_init) + if (Var->isConstexpr() && Var->isStaticDataMember() && + !Var->isThisDeclarationADefinition()) { + Diag(Var->getLocation(), diag::err_constexpr_static_mem_var_requires_init) << Var->getDeclName(); Var->setInvalidDecl(); return; @@ -6533,15 +6518,21 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } } - // Check for global constructors. + Expr *Init = var->getInit(); + bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal(); + if (!var->getDeclContext()->isDependentContext() && - var->hasGlobalStorage() && - !var->isStaticLocal() && - var->getInit() && - !var->getInit()->isConstantInitializer(Context, - baseType->isReferenceType())) - Diag(var->getLocation(), diag::warn_global_constructor) - << var->getInit()->getSourceRange(); + (var->isConstexpr() || IsGlobal) && Init && + !Init->isConstantInitializer(Context, baseType->isReferenceType())) { + // FIXME: Improve this diagnostic to explain why the initializer is not + // a constant expression. + if (var->isConstexpr()) + Diag(var->getLocation(), diag::err_constexpr_var_requires_const_init) + << var << Init->getSourceRange(); + if (IsGlobal) + Diag(var->getLocation(), diag::warn_global_constructor) + << Init->getSourceRange(); + } // Require the destructor. if (const RecordType *recordType = baseType->getAs<RecordType>()) |