[clang] [Clang] prevent assertion failure from an invalid template instantiation pattern when adding instantiated params to the scope in friend functions with defaulted params (PR #113777)
Matheus Izvekov via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 5 13:33:55 PST 2024
================
@@ -3430,15 +3430,17 @@ bool Sema::SubstDefaultArgument(
ContextRAII SavedContext(*this, FD);
std::unique_ptr<LocalInstantiationScope> LIS;
- if (ForCallExpr) {
+ FunctionDecl *PatternFD =
+ ForCallExpr
+ ? FD->getTemplateInstantiationPattern(/*ForDefinition*/ false)
+ : nullptr;
+ if (PatternFD) {
// When instantiating a default argument due to use in a call expression,
// an instantiation scope that includes the parameters of the callee is
// required to satisfy references from the default argument. For example:
// template<typename T> void f(T a, int = decltype(a)());
// void g() { f(0); }
LIS = std::make_unique<LocalInstantiationScope>(*this);
- FunctionDecl *PatternFD = FD->getTemplateInstantiationPattern(
- /*ForDefinition*/ false);
----------------
mizvekov wrote:
I think the actual problem here is that `getTemplateInstantiationPattern` doesn't work for finding the non-defining friend declaration in the class template.
This approach of skipping adding the parameters to the instantiation scope would only work in the simple case where the default argument definition doesn't refer to any of the parameters. The tests added in this PR doesn't cover the non-trivial case where it does refer to them.
Moreover, the whole previous approach seems fraught, as each default argument definition could appear in a different templated context, so there is not one single function template declaration which would serve as a pattern for all default arguments.
https://github.com/llvm/llvm-project/pull/113777
More information about the cfe-commits
mailing list