[cfe-commits] PR12937 - explicitly deleting an explicit template specialization

Douglas Gregor dgregor at apple.com
Mon Jun 25 11:14:27 PDT 2012


On Jun 25, 2012, at 11:08 AM, David Blaikie <dblaikie at gmail.com> wrote:

> On Mon, Jun 25, 2012 at 8:52 AM, Douglas Gregor <dgregor at apple.com> wrote:
>> 
>> On Jun 21, 2012, at 3:14 PM, David Blaikie wrote:
>> 
>>> As per PR12937 Clang rejects valid code that attempts to explicitly
>>> delete an explicit template specialization.
>>> 
>>> This is due to the way Clang represents explicit template
>>> specializations as redeclarations of an implicit specialization of the
>>> original function template.
>>> 
>>> The fix is a pretty vague workaround - I'm open to suggestions of how
>>> to more deliberately test for the "magic" implicit declaration for an
>>> explicit specialization but I couldn't find one - so for now I just
>>> assume it's the first (getPreviousDecl() == nullptr) declaration of
>>> any explicit specialization.
>> 
>> diff --git lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclCXX.cpp
>> index 8280835..dab2d4d 100644
>> --- lib/Sema/SemaDeclCXX.cpp
>> +++ lib/Sema/SemaDeclCXX.cpp
>> @@ -10316,8 +10316,13 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
>>     return;
>>   }
>>   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) {
>> -    Diag(DelLoc, diag::err_deleted_decl_not_first);
>> -    Diag(Prev->getLocation(), diag::note_previous_declaration);
>> +    // Don't consider the implicit declaration we generate for explicit
>> +    // specializations. FIXME: Do not generate these implicit declarations.
>> +    if (Prev->getTemplateSpecializationKind() != TSK_ExplicitSpecialization
>> +        || Prev->getPreviousDecl()) {
>> +      Diag(DelLoc, diag::err_deleted_decl_not_first);
>> +      Diag(Prev->getLocation(), diag::note_previous_declaration);
>> +    }
>>     // If the declaration wasn't the first, we delete the function anyway for
>>     // recovery.
>>   }
>> 
>> I suggest checking that Prev->getTemplateSpecializationKind() == TSK_ImplicitInstantiation. The others (explicit instantiations) should still, presumably, cause us to complain.
> 
> Just replacing my check with this would then cause us to lose the
> normal (non-templated) case. Assuming you meant testing both
> TSK_Undefined || TSK_ImplicitInstantiation, even then I'm a little
> confused - what cases would this correctly error on that my version
> did not?

I was concerned with explicit instantiations, e.g.,

	template void func2<int>();

> If it's any clearer, the condition I meant to express was: "if this is
> an explicit specialization with only one prior declaration, do not
> error" - perhaps it would be more legible as
> "!(Prev->getTemplateSpecializationKind() == TSK_ExplicitSpecalization
> && !Prev->getPreviousDecl())" ?

Okay. As long as the explicit instantiation example DTRT, either formulation is fine.

	- Doug

>> Otherwise, this looks good!
>> 
>>> At some point it would be nice to clean up the AST to more accurately
>>> represent the C++ semantics here so we don't have to do such hurdles.
>>> <pr12937.diff>
>> 
>> Yes, that would be a wonderful cleanup to our handling of template argument deduction.
>> 
>>        - Doug
>> 




More information about the cfe-commits mailing list