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
   


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to