From: Richard Smith Date: Thu, 6 Oct 2011 09:21:12 +0000 (+0000) Subject: PR11067: A definition of a constexpr static variable doesn't need an initializer... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b52c0dddffdb27b3a058913020001afcfc937d8d;p=clang PR11067: A definition of a constexpr static variable doesn't need an initializer if the in-class declaration had one. Such a declaration must be initialized by a constant expression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141279 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5f36f18656..fc8c636bb3 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1192,8 +1192,6 @@ def err_invalid_constexpr_var_decl : Error< "constexpr variable declaration must be a definition">; def err_constexpr_var_requires_init : Error< "declaration of constexpr variable %0 requires an initializer">; -def err_constexpr_initialized_static_member : Error< - "definition of initialized static data member %0 cannot be marked constexpr">; def err_constexpr_var_requires_const_init : Error< "constexpr variable %0 must be initialized by a constant expression">; def err_constexpr_redecl_mismatch : Error< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 1974f30b8e..718a19b988 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6032,15 +6032,12 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, // 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. - if (Var->isConstexpr()) { - // FIXME: Provide fix-its to convert the constexpr to const. - if (Var->isStaticDataMember() && Var->getAnyInitializer()) { - Diag(Var->getLocation(), diag::err_constexpr_initialized_static_member) - << Var->getDeclName(); - } else { - Diag(Var->getLocation(), diag::err_constexpr_var_requires_init) - << Var->getDeclName(); - } + // + // 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) + << Var->getDeclName(); Var->setInvalidDecl(); return; } diff --git a/test/CXX/class/class.static/class.static.data/p3.cpp b/test/CXX/class/class.static/class.static.data/p3.cpp index 031c376648..82460c5d96 100644 --- a/test/CXX/class/class.static/class.static.data/p3.cpp +++ b/test/CXX/class/class.static/class.static.data/p3.cpp @@ -10,6 +10,7 @@ struct S { static constexpr int c = 0; static const int d; + static const int d2 = 0; static constexpr double e = 0.0; // ok static const double f = 0.0; // expected-warning {{extension}} expected-note {{use 'constexpr' specifier}} @@ -17,8 +18,9 @@ struct S { static const NonLit h = NonLit(); // expected-error {{must be initialized out of line}} }; -constexpr int S::a; // expected-error {{definition of initialized static data member 'a' cannot be marked constexpr}} +constexpr int S::a; constexpr int S::b = 0; const int S::c; constexpr int S::d = 0; +constexpr int S::d2;