[cfe-commits] r144028 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/class/class.static/class.static.data/p3.cpp test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Nov 7 14:16:17 PST 2011


Author: rsmith
Date: Mon Nov  7 16:16:17 2011
New Revision: 144028

URL: http://llvm.org/viewvc/llvm-project?rev=144028&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=144028&r1=144027&r2=144028&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Nov  7 16:16:17 2011
@@ -1250,8 +1250,8 @@
   "constexpr can only be used in variable and function declarations">;
 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_static_mem_var_requires_init : Error<
+  "declaration of constexpr static data member %0 requires an initializer">;
 def err_constexpr_var_requires_const_init : Error<
   "constexpr variable %0 must be initialized by a constant expression">;
 def err_constexpr_redecl_mismatch : Error<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=144028&r1=144027&r2=144028&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Nov  7 16:16:17 2011
@@ -6191,17 +6191,6 @@
   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 @@
       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 @@
     }
   }
 
-  // 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>())

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=144028&r1=144027&r2=144028&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov  7 16:16:17 2011
@@ -8972,16 +8972,6 @@
   
   Expr *Init = Result.get();
   CheckImplicitConversions(Init, LParenLoc);
-  
-  if (VDecl->isConstexpr() && !VDecl->isInvalidDecl() &&
-      !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);
   VDecl->setInit(Init);

Modified: cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp?rev=144028&r1=144027&r2=144028&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp (original)
+++ cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp Mon Nov  7 16:16:17 2011
@@ -6,7 +6,7 @@
 
 struct S {
   static constexpr int a = 0;
-  static constexpr int b; // expected-error {{declaration of constexpr variable 'b' requires an initializer}}
+  static constexpr int b; // expected-error {{declaration of constexpr static data member 'b' requires an initializer}}
 
   static constexpr int c = 0;
   static const int d;

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp?rev=144028&r1=144027&r2=144028&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp Mon Nov  7 16:16:17 2011
@@ -20,7 +20,7 @@
 // not a definition of an object
 constexpr extern int i2; // expected-error {{constexpr variable declaration must be a definition}}
 // not a literal type
-constexpr notlit nl1; // expected-error {{declaration of constexpr variable 'nl1' requires an initializer}}
+constexpr notlit nl1; // expected-error {{constexpr variable 'nl1' must be initialized by a constant expression}}
 // function parameters
 void f2(constexpr int i) {} // expected-error {{function parameter cannot be constexpr}}
 // non-static member

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp?rev=144028&r1=144027&r2=144028&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp Mon Nov  7 16:16:17 2011
@@ -17,9 +17,9 @@
 
 // A variable declaration which uses the constexpr specifier shall have an
 // initializer and shall be initialized by a constant expression.
-constexpr int ni1; // expected-error {{declaration of constexpr variable 'ni1' requires an initializer}}
-constexpr struct C { C(); } ni2; // expected-error {{declaration of constexpr variable 'ni2' requires an initializer}}
-constexpr double &ni3; // expected-error {{declaration of constexpr variable 'ni3' requires an initializer}}
+constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}}
+constexpr struct C { C(); } ni2; // expected-error {{constexpr variable 'ni2' must be initialized by a constant expression}}
+constexpr double &ni3; // expected-error {{declaration of reference variable 'ni3' requires an initializer}}
 
 constexpr int nc1 = i; // expected-error {{constexpr variable 'nc1' must be initialized by a constant expression}}
 constexpr C nc2 = C(); // expected-error {{constexpr variable 'nc2' must be initialized by a constant expression}}
@@ -34,4 +34,4 @@
   int x, y;
 };
 constexpr pixel ur = { 1294, 1024 }; // ok
-constexpr pixel origin;              // expected-error {{requires an initializer}}
+constexpr pixel origin;              // expected-error {{default initialization of an object of const type 'const pixel' requires a user-provided default constructor}}





More information about the cfe-commits mailing list