[clang] [Clang] Stop changing DC when instantiating dependent friend specializations (PR #139436)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Mon May 12 02:17:38 PDT 2025
================
@@ -5751,14 +5751,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
RebuildTypeSourceInfoForDefaultSpecialMembers();
SetDeclDefaulted(Function, PatternDecl->getLocation());
} else {
- NamedDecl *ND = Function;
- DeclContext *DC = ND->getLexicalDeclContext();
+ DeclContext *DC = Function->getLexicalDeclContext();
std::optional<ArrayRef<TemplateArgument>> Innermost;
- if (auto *Primary = Function->getPrimaryTemplate();
- Primary &&
+ bool NeedDCFromPrimaryTemplate =
!isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function) &&
Function->getTemplateSpecializationKind() !=
- TSK_ExplicitSpecialization) {
+ TSK_ExplicitSpecialization &&
+ !PatternDecl->getDependentSpecializationInfo();
----------------
zyn0217 wrote:
That's the first approach I've tried :)
There are some challenges stopping us from treating it as a TSK_ExplicitSpecialization. And it comes from the discrepancy between the parser and instantiator.
When parsing the friend specialization within a class context, we treat it as an explicit specialization, and we diagnose it very early, in ActOnFriendFunctionDecl.
When instantiating, we consider *all* instantiated friend declarations as implicit instantiations, and we hold this assumption all the way down to the definition instantiation.
https://github.com/llvm/llvm-project/blob/4b893398990c8966402d1469c927415f5489a9c8/clang/lib/Sema/SemaTemplate.cpp#L9356-L9358
So we ended up with an awkward situation:
1. The definition is written in explicit specialization form, but gets implicitly instantiated within the class.
2. The instantiator attaches the implicit instantiation to the first template declaration as its primary template, which doesn't have a definition, nor any other instantiations have the IsInstantiatedFromMemberTemplate bit (because they're basically instantiated from a non-template!)
Combined, we violate the assertion in instantiating the definition.
Teaching the instantiator to treat it them as explicit instantiations would break many existing assumptions, as in ExplicitSpecializationVisibilityChecker.
https://github.com/llvm/llvm-project/pull/139436
More information about the cfe-commits
mailing list