Hi rsmith,

If the template has two variadic formal parameters, then the type
might not be canonical.  We have call ASTContext.getCanonicalType()
to canonicalize the type; otherwise, an assertion failure will be
raised.

This patch fix this issue by adding getCanonicalType() in
TransformTemplateTypeParmType.

http://reviews.llvm.org/D4343

Files:
  lib/Sema/SemaTemplateInstantiate.cpp
  test/SemaTemplate/alias-templates.cpp

Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1376,7 +1376,7 @@
     assert(Arg.getKind() == TemplateArgument::Type &&
            "Template argument kind mismatch");
 
-    QualType Replacement = Arg.getAsType();
+    QualType Replacement = getSema().Context.getCanonicalType(Arg.getAsType());
 
     // TODO: only do this uniquing once, at the start of instantiation.
     QualType Result
Index: test/SemaTemplate/alias-templates.cpp
===================================================================
--- test/SemaTemplate/alias-templates.cpp
+++ test/SemaTemplate/alias-templates.cpp
@@ -201,3 +201,17 @@
   template <typename T, typename U, typename V>
   using derived2 = ::PR16904::base<T, U>::template derived<V>; // 
expected-error {{expected a type}} expected-error {{expected ';'}}
 }
+
+namespace VariadicTemplateAlias {
+  template <typename... T> struct tuple;
+  template <typename... T> struct extract_;
+
+  // Note: Both the template alias and the concatenation of variadic template
+  // arguments A and B are required to trigger the assertion failure.
+
+  template <typename... T>
+  using extract = typename extract_<T...>::type;
+
+  template <typename... A, typename... B>
+  inline auto test(tuple<A...>&& xs, B&&... ys) -> extract<A&&..., B...> { }
+}
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1376,7 +1376,7 @@
     assert(Arg.getKind() == TemplateArgument::Type &&
            "Template argument kind mismatch");
 
-    QualType Replacement = Arg.getAsType();
+    QualType Replacement = getSema().Context.getCanonicalType(Arg.getAsType());
 
     // TODO: only do this uniquing once, at the start of instantiation.
     QualType Result
Index: test/SemaTemplate/alias-templates.cpp
===================================================================
--- test/SemaTemplate/alias-templates.cpp
+++ test/SemaTemplate/alias-templates.cpp
@@ -201,3 +201,17 @@
   template <typename T, typename U, typename V>
   using derived2 = ::PR16904::base<T, U>::template derived<V>; // expected-error {{expected a type}} expected-error {{expected ';'}}
 }
+
+namespace VariadicTemplateAlias {
+  template <typename... T> struct tuple;
+  template <typename... T> struct extract_;
+
+  // Note: Both the template alias and the concatenation of variadic template
+  // arguments A and B are required to trigger the assertion failure.
+
+  template <typename... T>
+  using extract = typename extract_<T...>::type;
+
+  template <typename... A, typename... B>
+  inline auto test(tuple<A...>&& xs, B&&... ys) -> extract<A&&..., B...> { }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to