diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 26693aa78cf2..2cc29caa0173 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1012,6 +1012,9 @@ def err_template_spec_friend : Error< def err_template_spec_default_arg : Error< "default argument not permitted on an explicit " "%select{instantiation|specialization}0 of function %1">; +def err_not_class_template_specialization : Error< + "cannot specialize a %select{dependent template|template template " + "parameter}0">; // C++ class template specializations and out-of-line definitions def err_template_spec_needs_header : Error< diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 9305d6ebb13e..419347adcf6a 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1188,7 +1188,9 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, if (TemplateSpecializationType::anyDependentTemplateArguments( TemplateArgs, - NumTemplateArgs)) { + NumTemplateArgs) || + isa(Template) || + Template->getDeclContext()->isDependentContext()) { // This class template specialization is a dependent // type. Therefore, its canonical type is another class template // specialization type that contains all of the converted @@ -2935,7 +2937,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // Find the class template we're specializing TemplateName Name = TemplateD.getAsVal(); ClassTemplateDecl *ClassTemplate - = cast(Name.getAsTemplateDecl()); + = dyn_cast_or_null(Name.getAsTemplateDecl()); + + if (!ClassTemplate) { + Diag(TemplateNameLoc, diag::err_not_class_template_specialization) + << (Name.getAsTemplateDecl() && + isa(Name.getAsTemplateDecl())); + return true; + } bool isExplicitSpecialization = false; bool isPartialSpecialization = false; diff --git a/clang/test/SemaTemplate/class-template-spec.cpp b/clang/test/SemaTemplate/class-template-spec.cpp index 4cd43b469ae0..5bc9a6cd67da 100644 --- a/clang/test/SemaTemplate/class-template-spec.cpp +++ b/clang/test/SemaTemplate/class-template-spec.cpp @@ -104,3 +104,8 @@ Foo* v; Foo& F() { return *v; } template class Foo {}; Foo x; + + +// Template template parameters +template class Wibble> +class Wibble { }; // expected-error{{cannot specialize a template template parameter}}