faisalv created this revision.
faisalv added a reviewer: rsmith.
faisalv added a subscriber: cfe-commits.

I'm not sure why this check wasn't being done at template definition time.  
I can't devise a test case to trigger the concerns in the deleted comments 
below.

Anything I might be missing by simply adding the CheckTemplateArgument check 
here?

Thanks!


http://reviews.llvm.org/D18495

Files:
  lib/Sema/SemaTemplate.cpp
  test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
  test/CXX/temp/temp.param/p10-0x.cpp
  test/CXX/temp/temp.param/p12.cpp

Index: test/CXX/temp/temp.param/p12.cpp
===================================================================
--- test/CXX/temp/temp.param/p12.cpp
+++ test/CXX/temp/temp.param/p12.cpp
@@ -34,6 +34,6 @@
 // Check validity of default arguments
 template<template<class, int> class // expected-note{{previous template template parameter is here}}
            = Y1> // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
-  class C1 {};
+  class C1 {};  //expected-note{{template is declared here}}
 
-C1<> c1; // expected-note{{while checking a default template argument}}
+C1<> c1; // expected-error{{too few template arguments}}
Index: test/CXX/temp/temp.param/p10-0x.cpp
===================================================================
--- test/CXX/temp/temp.param/p10-0x.cpp
+++ test/CXX/temp/temp.param/p10-0x.cpp
@@ -8,7 +8,7 @@
 template<class T1 = int, class T2> using B2 = T1;
 
 template<template<class> class F, template<class> class G = Y1> using B2t = F<G<int>>;
-template<template<class> class F = Y2, template<class> class G> using B2t = F<G<int>>;
+template<template<class> class F = Y1, template<class> class G> using B2t = F<G<int>>;
 
 template<int N, int M = 5> using B2n = Y2<int, N + M>;
 template<int N = 5, int M> using B2n = Y2<int, N + M>;
Index: test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
===================================================================
--- test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
+++ test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
@@ -38,3 +38,51 @@
 X1<long, X1b> inst_x1b;
 X1<short, X1c> inst_x1c;
 X1<short, X1d> inst_x1d; // expected-error{{template template argument has different template parameters than its corresponding template template paramete}}
+
+
+namespace ns0 {
+template<class, class> using TA = int*;
+template<template<class, class> class TT = TA> struct X;
+
+}
+
+
+namespace ns1 {
+template<template<class, class> class TT> //expected-note{{too many template parameters}}
+struct X {
+  template<template<class> //expected-note{{previous template template parameter is here}}
+              class UU = TT>  //expected-error{{different template parameters}}
+  struct Y;
+};
+} // end ns1
+namespace ns2 {
+template<class T, template<T, class> class TT> 
+struct A {
+  template<class U, template<U, class...> class UU = TT> 
+  struct B;
+};
+} // end ns2
+namespace ns3 {
+template<class T, template<T, class...> class TT> struct A {
+  template<class U, template<U, class> class UU = T::template X> struct B { };
+};
+} // end ns3
+namespace ns4 {
+template<class T, template<T, class...> class TT> //expected-note{{pack does not match}}
+struct A {
+  template<class U, template<U, class> //expected-note{{declared here}}
+      class UU = TT> //expected-error{{different template parameters}}
+  struct B;
+};
+
+} // end ns4
+
+namespace ns5 {
+template<class T, template<T, class...> class TT> 
+struct A {
+  template<class U, template<U, class...> 
+      class UU = TT> 
+  struct B;
+};
+
+} // end ns5
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -790,14 +790,6 @@
   }
 
   if (!Default.isInvalid()) {
-    // Check only that we have a template template argument. We don't want to
-    // try to check well-formedness now, because our template template parameter
-    // might have dependent types in its template parameters, which we wouldn't
-    // be able to match now.
-    //
-    // If none of the template template parameter's template arguments mention
-    // other template parameters, we could actually perform more checking here.
-    // However, it isn't worth doing.
     TemplateArgumentLoc DefaultArg = translateTemplateArgument(*this, Default);
     if (DefaultArg.getArgument().getAsTemplate().isNull()) {
       Diag(DefaultArg.getLocation(), diag::err_template_arg_not_valid_template)
@@ -810,7 +802,11 @@
                                         DefaultArg.getArgument().getAsTemplate(),
                                         UPPC_DefaultArgument))
       return Param;
-
+    // Check that the default template template argument is compatible with 
+    // the template template parameter, in as much as we can check at this
+    // time.
+    if (CheckTemplateArgument(Param, DefaultArg, 0)) 
+      return Param;
     Param->setDefaultArgument(Context, DefaultArg);
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to