Implement a specific diagnostic when a class template partial

specialization does not use any of its template parameters, then
recover far more gracefully. Fixes PR6181.

llvm-svn: 95629
This commit is contained in:
Douglas Gregor 2010-02-09 00:37:32 +00:00
parent 9f85e7eb16
commit 92354b6b55
3 changed files with 35 additions and 9 deletions

View File

@ -1271,6 +1271,8 @@ def err_partial_spec_redeclared : Error<
"class template partial specialization %0 cannot be redeclared">;
def note_prev_partial_spec_here : Note<
"previous declaration of class template partial specialization %0 is here">;
def err_partial_spec_fully_specialized : Error<
"partial specialization of %0 does not use any of its template parameters">;
// C++ Function template specializations
def err_function_template_spec_no_match : Error<

View File

@ -3400,12 +3400,23 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// FIXME: Diagnose friend partial specializations
// FIXME: Template parameter list matters, too
ClassTemplatePartialSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
Converted.flatSize(),
Context);
} else
if (!Name.isDependent() &&
!TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs.getArgumentArray(),
TemplateArgs.size())) {
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
<< ClassTemplate->getDeclName();
isPartialSpecialization = false;
} else {
// FIXME: Template parameter list matters, too
ClassTemplatePartialSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
Converted.flatSize(),
Context);
}
}
if (!isPartialSpecialization)
ClassTemplateSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
Converted.flatSize(),
@ -3435,7 +3446,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
QualType CanonType;
if (PrevDecl &&
(PrevDecl->getSpecializationKind() == TSK_Undeclared ||
TUK == TUK_Friend)) {
TUK == TUK_Friend)) {
// Since the only prior class template specialization with these
// arguments was referenced but not declared, or we're only
// referencing this specialization as a friend, reuse that
@ -3448,8 +3459,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
} else if (isPartialSpecialization) {
// Build the canonical type that describes the converted template
// arguments of the class template partial specialization.
CanonType = Context.getTemplateSpecializationType(
TemplateName(ClassTemplate),
TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
CanonType = Context.getTemplateSpecializationType(CanonTemplate,
Converted.getFlatArguments(),
Converted.flatSize());

View File

@ -348,3 +348,16 @@ namespace PR6025 {
{
};
}
namespace PR6181 {
template <class T>
class a;
class s;
template <class U>
class a<s> // expected-error{{partial specialization of 'a' does not use any of its template parameters}}
{
};
}