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
