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.
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 ();
--- /dev/null
+// PR c++/119574
+// { dg-do compile { target c++20 } }
+
+template <class F = decltype([] <auto G = [] {}> () {})>
+void f(F op = {}) { op(); }
+
+int main() { f(); }
--- /dev/null
+// 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(); }