r198833 - PR18401: Fix assert by implementing the current proposed direction of core

Richard Smith richard-llvm at metafoo.co.uk
Wed Jan 8 18:22:22 PST 2014


Author: rsmith
Date: Wed Jan  8 20:22:22 2014
New Revision: 198833

URL: http://llvm.org/viewvc/llvm-project?rev=198833&view=rev
Log:
PR18401: Fix assert by implementing the current proposed direction of core
issue 1430. Don't allow a pack expansion to be used as an argument to an alias
template unless the corresponding parameter is a parameter pack.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
    cfe/trunk/test/CodeGenCXX/mangle-alias-template.cpp
    cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=198833&r1=198832&r2=198833&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jan  8 20:22:22 2014
@@ -3414,6 +3414,8 @@ def note_template_declared_here : Note<
   "%select{function template|class template|variable template"
   "|type alias template|template template parameter}0 "
   "%1 declared here">;
+def err_alias_template_expansion_into_fixed_list : Error<
+  "pack expansion used as argument for non-pack parameter of alias template">;
 def note_parameter_type : Note<
   "parameter of type %0 is declared here">;
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=198833&r1=198832&r2=198833&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Jan  8 20:22:22 2014
@@ -5298,18 +5298,12 @@ public:
   /// \param Converted Will receive the converted, canonicalized template
   /// arguments.
   ///
-  ///
-  /// \param ExpansionIntoFixedList If non-NULL, will be set true to indicate
-  /// when the template arguments contain a pack expansion that is being
-  /// expanded into a fixed parameter list.
-  ///
-  /// \returns True if an error occurred, false otherwise.
+  /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(TemplateDecl *Template,
                                  SourceLocation TemplateLoc,
                                  TemplateArgumentListInfo &TemplateArgs,
                                  bool PartialTemplateArgs,
-                           SmallVectorImpl<TemplateArgument> &Converted,
-                                 bool *ExpansionIntoFixedList = 0);
+                           SmallVectorImpl<TemplateArgument> &Converted);
 
   bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
                                  const TemplateArgumentLoc &Arg,

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=198833&r1=198832&r2=198833&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jan  8 20:22:22 2014
@@ -1975,17 +1975,15 @@ QualType Sema::CheckTemplateIdType(Templ
   // Check that the template argument list is well-formed for this
   // template.
   SmallVector<TemplateArgument, 4> Converted;
-  bool ExpansionIntoFixedList = false;
   if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
-                                false, Converted, &ExpansionIntoFixedList))
+                                false, Converted))
     return QualType();
 
   QualType CanonType;
 
   bool InstantiationDependent = false;
-  TypeAliasTemplateDecl *AliasTemplate = 0;
-  if (!ExpansionIntoFixedList &&
-      (AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Template))) {
+  if (TypeAliasTemplateDecl *AliasTemplate =
+          dyn_cast<TypeAliasTemplateDecl>(Template)) {
     // Find the canonical type for this type alias template specialization.
     TypeAliasDecl *Pattern = AliasTemplate->getTemplatedDecl();
     if (Pattern->isInvalidDecl())
@@ -2590,11 +2588,10 @@ Sema::CheckVarTemplateId(VarTemplateDecl
 
   // Check that the template argument list is well-formed for this template.
   SmallVector<TemplateArgument, 4> Converted;
-  bool ExpansionIntoFixedList = false;
   if (CheckTemplateArgumentList(
           Template, TemplateNameLoc,
           const_cast<TemplateArgumentListInfo &>(TemplateArgs), false,
-          Converted, &ExpansionIntoFixedList))
+          Converted))
     return true;
 
   // Find the variable template specialization declaration that
@@ -3549,11 +3546,7 @@ bool Sema::CheckTemplateArgumentList(Tem
                                      SourceLocation TemplateLoc,
                                      TemplateArgumentListInfo &TemplateArgs,
                                      bool PartialTemplateArgs,
-                          SmallVectorImpl<TemplateArgument> &Converted,
-                                     bool *ExpansionIntoFixedList) {
-  if (ExpansionIntoFixedList)
-    *ExpansionIntoFixedList = false;
-
+                          SmallVectorImpl<TemplateArgument> &Converted) {
   TemplateParameterList *Params = Template->getTemplateParameters();
 
   SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc();
@@ -3606,6 +3599,20 @@ bool Sema::CheckTemplateArgumentList(Tem
                                 ArgumentPack.size(), Converted))
         return true;
 
+      if (TemplateArgs[ArgIdx].getArgument().isPackExpansion() &&
+          isa<TypeAliasTemplateDecl>(Template) &&
+          !(Param + 1 == ParamEnd && (*Param)->isTemplateParameterPack() &&
+            !getExpandedPackSize(*Param))) {
+        // Core issue 1430: we have a pack expansion as an argument to an
+        // alias template, and it's not part of a final parameter pack. This
+        // can't be canonicalized, so reject it now.
+        Diag(TemplateArgs[ArgIdx].getLocation(),
+             diag::err_alias_template_expansion_into_fixed_list)
+          << TemplateArgs[ArgIdx].getSourceRange();
+        Diag((*Param)->getLocation(), diag::note_template_param_here);
+        return true;
+      }
+
       // We're now done with this argument.
       ++ArgIdx;
 
@@ -3652,9 +3659,6 @@ bool Sema::CheckTemplateArgumentList(Tem
                                              ArgumentPack.data(),
                                              ArgumentPack.size()));
           ArgumentPack.clear();
-        } else if (ExpansionIntoFixedList) {
-          // We have expanded a pack into a fixed list.
-          *ExpansionIntoFixedList = true;
         }
 
         return false;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=198833&r1=198832&r2=198833&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Jan  8 20:22:22 2014
@@ -2480,11 +2480,10 @@ Decl *TemplateDeclInstantiator::VisitVar
 
   // Check that the template argument list is well-formed for this template.
   SmallVector<TemplateArgument, 4> Converted;
-  bool ExpansionIntoFixedList = false;
   if (SemaRef.CheckTemplateArgumentList(
           VarTemplate, VarTemplate->getLocStart(),
           const_cast<TemplateArgumentListInfo &>(VarTemplateArgsInfo), false,
-          Converted, &ExpansionIntoFixedList))
+          Converted))
     return 0;
 
   // Find the variable template specialization declaration that

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp?rev=198833&r1=198832&r2=198833&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp Wed Jan  8 20:22:22 2014
@@ -121,7 +121,16 @@ namespace PartialSpecialization {
 
 namespace FixedAliasTemplate {
   template<typename,typename,typename> struct S {};
-  template<typename T, typename U> using U = S<T, int, U>;
-  template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...);
-  S<int, int, double> &s1 = f({}, 0, 0.0);
+  template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}}
+  template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}}
+  S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}}
+}
+
+namespace PR18401 {
+  template<typename... Args> struct foo { };
+  template<typename T, typename... Args> using bar = foo<T, Args...>; // expected-note 2{{template parameter is declared here}} expected-note {{'bar' declared here}}
+  template<typename T, typename... Args> using baz = bar<Args..., T>; // expected-error {{pack expansion used as argument for non-pack parameter of alias template}}
+  // FIXME: We should still record the alias template, but mark it as invalid.
+  template<typename...T> void f(baz<T...>); // expected-error {{no template named 'baz'; did you mean 'bar'}} expected-error {{pack expansion used as argument for non-pack}}
+  void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}}
 }

Modified: cfe/trunk/test/CodeGenCXX/mangle-alias-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-alias-template.cpp?rev=198833&r1=198832&r2=198833&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-alias-template.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-alias-template.cpp Wed Jan  8 20:22:22 2014
@@ -11,10 +11,6 @@ template<typename T> void g(T);
 
 template<template<typename> class F> void h(F<int>);
 
-template<typename,typename,typename> struct S {};
-template<typename T, typename U> using U = S<T, int, U>;
-template<typename...Ts> void h(U<Ts...>, Ts...);
-
 // CHECK-LABEL: define void @_Z1zv(
 void z() {
   vector<int> VI;
@@ -42,7 +38,4 @@ void z() {
   Vec<Vec<int>> VVI;
   g(VVI);
   // CHECK: call void @_Z1gI6vectorIS0_Ii5allocIiEES1_IS3_EEEvT_(
-
-  // CHECK: call void @_Z1hIJidEEv1UIDpT_ES2_
-  h({}, 0, 0.0);
 }

Modified: cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp?rev=198833&r1=198832&r2=198833&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp Wed Jan  8 20:22:22 2014
@@ -3,6 +3,9 @@
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
 
+template<class F, class ...Rest> struct first_impl { typedef F type; };
+template<class ...Args> using first = typename first_impl<Args...>::type;
+
 namespace simple_explicit_capture {
   void test() {
     int i;
@@ -497,8 +500,6 @@ int run = fooT('a') + fooT(3.14);
 
 template<class ... Ts> void print(Ts ... ts) { }
 
-template<class F, class ... Rest> using first = F;
-
 template<class ... Ts> auto fooV(Ts ... ts) {
   auto L = [](auto ... a) { 
     auto M = [](decltype(a) ... b) {  
@@ -568,7 +569,6 @@ int (*np2)(const char*, int, const char*
 namespace variadic_tests_1 {
 template<class ... Ts> void print(Ts ... ts) { }
 
-template<class F, class ... Rest> using FirstType = F;
 template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; }
  
 template<class ... Ts> int fooV(Ts ... ts) {
@@ -582,7 +582,7 @@ template<class ... Ts> int fooV(Ts ... t
       };  
       N('a');
       N(N);
-      N(FirstType<Ts...>{});
+      N(first<Ts...>{});
     };
     M(a...);
     print("a = ", a..., "\n");    
@@ -607,7 +607,7 @@ template<class ... Ts> int fooV(Ts ... t
       };  
       N('a');
       N(N);
-      N(FirstType<Ts...>{});
+      N(first<Ts...>{});
     };
     M(a...);
     return M;
@@ -627,7 +627,7 @@ template<class ... Ts> int fooV(Ts ... t
         };  
         N('a');
         N(N);
-        N(FirstType<Ts...>{});
+        N(first<Ts...>{});
         return N;
       };
       M(a...);
@@ -771,7 +771,6 @@ int run = test();
 
 
 namespace fptr_with_decltype_return_type {
-template<class F, class ... Ts> using FirstType = F;
 template<class F, class ... Rest> F& FirstArg(F& f, Rest& ... r) { return f; };
 template<class ... Ts> auto vfun(Ts&& ... ts) {
   print(ts...);
@@ -782,7 +781,7 @@ int test()
  {
    auto L = [](auto ... As) {
     return [](auto b) ->decltype(b) {   
-      vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(FirstType<decltype(As)...>{});
+      vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(first<decltype(As)...>{});
       return decltype(b){};
     };
    };
@@ -913,4 +912,4 @@ int run2 = x2.fooG3();
 
 
 
-} //end ns inclass_lambdas_within_nested_classes
\ No newline at end of file
+} //end ns inclass_lambdas_within_nested_classes





More information about the cfe-commits mailing list