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); } 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 inst_x1b; X1 inst_x1c; X1 inst_x1d; // expected-error{{template template argument has different template parameters than its corresponding template template paramete}} + + +namespace ns0 { +template using TA = int*; +template class TT = TA> struct X; + +} + + +namespace ns1 { +template class TT> //expected-note{{too many template parameters}} +struct X { + template //expected-note{{previous template template parameter is here}} + class UU = TT> //expected-error{{different template parameters}} + struct Y; +}; +} // end ns1 +namespace ns2 { +template class TT> +struct A { + template class UU = TT> + struct B; +}; +} // end ns2 +namespace ns3 { +template class TT> struct A { + template class UU = T::template X> struct B { }; +}; +} // end ns3 +namespace ns4 { +template class TT> //expected-note{{pack does not match}} +struct A { + template //expected-note{{declared here}} + class UU = TT> //expected-error{{different template parameters}} + struct B; +}; + +} // end ns4 + +namespace ns5 { +template class TT> +struct A { + template + class UU = TT> + struct B; +}; + +} // end ns5 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 using B2 = T1; template class F, template class G = Y1> using B2t = F>; -template class F = Y2, template class G> using B2t = F>; +template class F = Y1, template class G> using B2t = F>; template using B2n = Y2; template using B2n = Y2; 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 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}}