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