On Mon, Jun 25, 2012 at 8:52 AM, Douglas Gregor <[email protected]> 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
>

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to