On Jun 25, 2012, at 11:08 AM, David Blaikie <[email protected]> wrote:

> 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?

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
>> 

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

Reply via email to