aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-11-07 22:16:17 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-11-07 22:16:17 +0000
commit66f85713bd0d22f867efa8e9fb0037befdd6b151 (patch)
treec0d06e5bda333ee32210eabdfac012b0e1554f0d /lib/Sema/SemaDecl.cpp
parent45fa560c72441069d9e4eb1e66efd87349caa552 (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.cpp43
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>())