[cfe-commits] r147273 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/FixIt/fixit-cxx0x.cpp test/SemaCXX/constant-expression-cxx11.cpp

Richard Smith richard-llvm at metafoo.co.uk
Sun Dec 25 13:17:58 PST 2011


Author: rsmith
Date: Sun Dec 25 15:17:58 2011
New Revision: 147273

URL: http://llvm.org/viewvc/llvm-project?rev=147273&view=rev
Log:
Fix constexpr handling to allow 'extern constexpr' variable declarations. We no
longer have access to the source locations we need to produce the
'replace constexpr with const' fixits, so they're gone for now.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/FixIt/fixit-cxx0x.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=147273&r1=147272&r2=147273&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Dec 25 15:17:58 2011
@@ -3948,38 +3948,8 @@
                                            TemplateParamLists.release());
     }
 
-    if (D.getDeclSpec().isConstexprSpecified()) {
-      // FIXME: once we know whether there's an initializer, apply this to
-      // static data members too.
-      if (!NewVD->isStaticDataMember() &&
-          !NewVD->isThisDeclarationADefinition()) {
-        // 'constexpr' is redundant and ill-formed on a non-defining declaration
-        // of a variable. Suggest replacing it with 'const' if appropriate.
-        SourceLocation ConstexprLoc = D.getDeclSpec().getConstexprSpecLoc();
-        SourceRange ConstexprRange(ConstexprLoc, ConstexprLoc);
-        // If the declarator is complex, we need to move the keyword to the
-        // innermost chunk as we switch it from 'constexpr' to 'const'.
-        int Kind = DeclaratorChunk::Paren;
-        for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) {
-          Kind = D.getTypeObject(I).Kind;
-          if (Kind != DeclaratorChunk::Paren)
-            break;
-        }
-        if ((D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ_const) ||
-            Kind == DeclaratorChunk::Reference)
-          Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl)
-            << FixItHint::CreateRemoval(ConstexprRange);
-        else if (Kind == DeclaratorChunk::Paren)
-          Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl)
-            << FixItHint::CreateReplacement(ConstexprRange, "const");
-        else
-          Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl)
-            << FixItHint::CreateRemoval(ConstexprRange)
-            << FixItHint::CreateInsertion(D.getIdentifierLoc(), "const ");
-      } else {
-        NewVD->setConstexpr(true);
-      }
-    }
+    if (D.getDeclSpec().isConstexprSpecified())
+      NewVD->setConstexpr(true);
   }
 
   // Set the lexical context. If the declarator has a C++ scope specifier, the
@@ -6244,7 +6214,7 @@
   if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) {
     QualType Type = Var->getType();
 
-    // C++0x [dcl.spec.auto]p3
+    // C++11 [dcl.spec.auto]p3
     if (TypeMayContainAuto && Type->getContainedAutoType()) {
       Diag(Var->getLocation(), diag::err_auto_var_requires_init)
         << Var->getDeclName() << Type;
@@ -6252,13 +6222,19 @@
       return;
     }
 
-    // C++0x [class.static.data]p3: A static data member can be declared with
+    // C++11 [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() && Var->isStaticDataMember() &&
-        !Var->isThisDeclarationADefinition()) {
-      Diag(Var->getLocation(), diag::err_constexpr_static_mem_var_requires_init)
-        << Var->getDeclName();
+    // C++11 [dcl.constexpr]p1: The constexpr specifier shall be applied only to
+    // the definition of a variable [...] or the declaration of a static data
+    // member.
+    if (Var->isConstexpr() && !Var->isThisDeclarationADefinition()) {
+      if (Var->isStaticDataMember())
+        Diag(Var->getLocation(),
+             diag::err_constexpr_static_mem_var_requires_init)
+          << Var->getDeclName();
+      else
+        Diag(Var->getLocation(), diag::err_invalid_constexpr_var_decl);
       Var->setInvalidDecl();
       return;
     }

Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=147273&r1=147272&r2=147273&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Sun Dec 25 15:17:58 2011
@@ -18,41 +18,6 @@
 using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
 using typename ::V = void; // expected-error {{name defined in alias declaration must be an identifier}}
 
-namespace Constexpr {
-  extern constexpr int a; // expected-error {{must be a definition}}
-  // -> extern const int a;
-
-  extern constexpr int *b; // expected-error {{must be a definition}}
-  // -> extern int *const b;
-
-  extern constexpr int &c; // expected-error {{must be a definition}}
-  // -> extern int &b;
-
-  extern constexpr const int d; // expected-error {{must be a definition}}
-  // -> extern const int d;
-
-  int z;
-  constexpr int a = 0;
-  constexpr int *b = &z;
-  constexpr int &c = z;
-  constexpr int d = a;
-
-  // FIXME: Provide FixIts for static data members too.
-#if 0
-  struct S {
-    static constexpr int b; // xpected-error {{requires an initializer}}
-    // -> const int b;
-  };
-
-  constexpr int S::b = 0;
-#endif
-
-  struct S {
-    static char *const p = 0; // expected-error {{requires 'constexpr' specifier}}
-    // -> constexpr static char *const p = 0;
-  };
-}
-
 namespace SemiCommaTypo {
   int m {},
   n [[]], // expected-error {{expected ';' at end of declaration}}

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=147273&r1=147272&r2=147273&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sun Dec 25 15:17:58 2011
@@ -961,3 +961,13 @@
 };
 
 }
+
+namespace ExternConstexpr {
+  extern constexpr int n = 0;
+  extern constexpr int m; // expected-error {{constexpr variable declaration must be a definition}}
+  void f() {
+    extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}}
+    constexpr int j = 0;
+    constexpr int k; // expected-error {{default initialization of an object of const type}}
+  }
+}





More information about the cfe-commits mailing list