r294785 - [c++1z] Require an initializer for deduced class template specialization types.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 10 13:40:29 PST 2017


Author: rsmith
Date: Fri Feb 10 15:40:29 2017
New Revision: 294785

URL: http://llvm.org/viewvc/llvm-project?rev=294785&view=rev
Log:
[c++1z] Require an initializer for deduced class template specialization types.

It's actually meaningful and useful to allow such variables to have no
initializer, but we are strictly following the standard here until the C++
committee reaches consensus on allowing this.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
    cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp
    cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Feb 10 15:40:29 2017
@@ -1893,7 +1893,7 @@ def err_dependent_deduced_tst : Error<
 def err_auto_not_allowed_var_inst : Error<
   "'auto' variable template instantiation is not allowed">;
 def err_auto_var_requires_init : Error<
-  "declaration of variable %0 with type %1 requires an initializer">;
+  "declaration of variable %0 with deduced type %1 requires an initializer">;
 def err_auto_new_requires_ctor_arg : Error<
   "new expression for type %0 requires a constructor argument">;
 def err_auto_new_list_init : Error<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Feb 10 15:40:29 2017
@@ -9816,7 +9816,15 @@ QualType Sema::deduceVarTypeFromInitiali
   DeducedType *Deduced = Type->getContainedDeducedType();
   assert(Deduced && "deduceVarTypeFromInitializer for non-deduced type");
 
-  ArrayRef<Expr*> DeduceInits = Init ? ArrayRef<Expr*>(Init) : None;
+  // C++11 [dcl.spec.auto]p3
+  if (!Init) {
+    assert(VDecl && "no init for init capture deduction?");
+    Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
+      << VDecl->getDeclName() << Type;
+    return QualType();
+  }
+
+  ArrayRef<Expr*> DeduceInits = Init;
   if (DirectInit) {
     if (auto *PL = dyn_cast_or_null<ParenListExpr>(Init))
       DeduceInits = PL->exprs();
@@ -9833,14 +9841,6 @@ QualType Sema::deduceVarTypeFromInitiali
                                                        InitsCopy);
   }
 
-  // C++11 [dcl.spec.auto]p3
-  if (!Init) {
-    assert(VDecl && "no init for init capture deduction?");
-    Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
-      << VDecl->getDeclName() << Type;
-    return QualType();
-  }
-
   if (DirectInit) {
     if (auto *IL = dyn_cast<InitListExpr>(Init))
       DeduceInits = IL->inits();

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp Fri Feb 10 15:40:29 2017
@@ -9,9 +9,9 @@ void f() {
 }
 
 void g() {
-  decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}}
+  decltype(auto) a; // expected-error{{declaration of variable 'a' with deduced type 'decltype(auto)' requires an initializer}}
   
-  decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}}
+  decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with deduced type 'decltype(auto) *' requires an initializer}}
 
   if (decltype(auto) b) {} // expected-error {{must have an initializer}}
   for (;decltype(auto) b;) {} // expected-error {{must have an initializer}}

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp Fri Feb 10 15:40:29 2017
@@ -9,9 +9,9 @@ void f() {
 }
 
 void g() {
-  auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}}
+  auto a; // expected-error{{declaration of variable 'a' with deduced type 'auto' requires an initializer}}
   
-  auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
+  auto *b; // expected-error{{declaration of variable 'b' with deduced type 'auto *' requires an initializer}}
 
   if (auto b) {} // expected-error {{must have an initializer}}
   for (;auto b;) {} // expected-error {{must have an initializer}}

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp Fri Feb 10 15:40:29 2017
@@ -36,7 +36,7 @@ class X {
 };
 
 struct S {
-  static const auto a; // expected-error {{declaration of variable 'a' with type 'const auto' requires an initializer}}
+  static const auto a; // expected-error {{declaration of variable 'a' with deduced type 'const auto' requires an initializer}}
   static const auto b = 0;
   static const int c;
 };

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp Fri Feb 10 15:40:29 2017
@@ -5,8 +5,14 @@ A() -> A<int>;
 A(int) -> A<char>;
 
 static constexpr inline const volatile A a = {}; // ok, specifiers are permitted
-A b; // FIXME: An initializer is required
+// FIXME: There isn't really a good reason to reject this.
+A b; // expected-error {{requires an initializer}}
 A c [[]] {};
 
 A d = {}, e = {};
 A f(0), g{}; // expected-error {{template arguments deduced as 'A<char>' in declaration of 'f' and deduced as 'A<int>' in declaration of 'g'}}
+
+struct B {
+  static A a; // expected-error {{requires an initializer}}
+};
+extern A x; // expected-error {{requires an initializer}}

Modified: cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp (original)
+++ cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp Fri Feb 10 15:40:29 2017
@@ -52,7 +52,7 @@ struct member {
 
   operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
 
-  static A x; // FIXME: We deduce A<int> from the initializer despite this not being a definition!
+  static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
   static constexpr A y = 0;
 };
 
@@ -127,7 +127,7 @@ namespace decl {
 
   auto k() -> A; // expected-error{{requires template arguments}}
 
-  A a; // FIXME: This is (technically) syntactically invalid.
+  A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}}
   A b = 0;
   const A c = 0;
   A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}

Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=294785&r1=294784&r2=294785&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp Fri Feb 10 15:40:29 2017
@@ -102,7 +102,7 @@ namespace odr_tmpl {
     template<typename T> extern int v;    // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}}
 
 #ifndef PRECXX11
-    template<typename T> extern auto v;   // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
+    template<typename T> extern auto v;   // expected-error {{declaration of variable 'v' with deduced type 'auto' requires an initializer}}
 #endif
 
     template<typename T> T var = T();     // expected-note {{previous definition is here}}
@@ -111,7 +111,7 @@ namespace odr_tmpl {
 
 #ifndef PRECXX11
   namespace pvt_auto {
-    template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
+    template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with deduced type 'auto' requires an initializer}}
     template<typename T> auto v1 = T();  // expected-note {{previous definition is here}}
     template<typename T> int v1;   // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
     template<typename T> auto v2 = T();  // expected-note {{previous definition is here}}
@@ -119,7 +119,7 @@ namespace odr_tmpl {
     template<typename T> auto v3 = T();   // expected-note {{previous definition is here}}
     template<typename T> extern T v3;     // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}}
     template<typename T> auto v4 = T();
-    template<typename T> extern auto v4;   // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
+    template<typename T> extern auto v4;   // expected-error {{declaration of variable 'v4' with deduced type 'auto' requires an initializer}}
   }
 #endif
   




More information about the cfe-commits mailing list