[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