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
