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

David Blaikie dblaikie at gmail.com
Mon Jun 25 11:08:31 PDT 2012


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?

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())" ?

> 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