https://gcc.gnu.org/g:ff5fdb3cad1a76768406e0fcec2010cdd72f49fc
commit r14-11577-gff5fdb3cad1a76768406e0fcec2010cdd72f49fc Author: Patrick Palka <ppa...@redhat.com> Date: Wed Apr 9 17:55:36 2025 -0400 c++: ICE with nested default targ lambdas [PR119574] In GCC 14 we fixed PR116567 in a more conservative way that doesn't distinguish between the two kinds of deferred substitutions, and so for PR119574 we instead ICE from get_innermost_template_args due to TMPL_PARMS_DEPTH of the lambda, 2, being greater than the depth of the augmented args, 1. This patch works around the ICE in a best effort kind of way by guarding the get_innermost_template_args call appropriately; I don't think it's possible to get this completely right in GCC 14 without backporting the proper fix for PR116567. Note that lambda-targ13b.C present in the GCC 15 version of this patch[1] never worked in GCC 14, and still doesn't work, which is why it's not present in this patch. [1]: r15-9350-gf3862ab07943d1 PR c++/119574 gcc/cp/ChangeLog: * pt.cc (tsubst_lambda_expr): Don't call get_innermost_template_args if we're requesting too many levels. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ13.C: New test. * g++.dg/cpp2a/lambda-targ13a.C: New test. Diff: --- gcc/cp/pt.cc | 3 ++- gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C | 7 +++++++ gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2efc7eb19e87..5b9a9c611f24 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -19708,7 +19708,8 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree ctx_parms = DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (oldfn)); if (generic_lambda_fn_p (oldfn)) ctx_parms = TREE_CHAIN (ctx_parms); - args = get_innermost_template_args (args, TMPL_PARMS_DEPTH (ctx_parms)); + if (TMPL_ARGS_DEPTH (args) > TMPL_PARMS_DEPTH (ctx_parms)) + args = get_innermost_template_args (args, TMPL_PARMS_DEPTH (ctx_parms)); } tree r = build_lambda_expr (); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C new file mode 100644 index 000000000000..8fd0a311e056 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C @@ -0,0 +1,7 @@ +// PR c++/119574 +// { dg-do compile { target c++20 } } + +template <class F = decltype([] <auto G = [] {}> () {})> +void f(F op = {}) { op(); } + +int main() { f(); } diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C new file mode 100644 index 000000000000..8aaefd93356c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C @@ -0,0 +1,8 @@ +// PR c++/119574 +// A version of lambda-targ13.C with extra template parameters. +// { dg-do compile { target c++20 } } + +template <int = 0, class F = decltype([] <int = 1, auto G = [] {}> () {})> +void f(F op = {}) { op(); } + +int main() { f(); }