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(); }

Reply via email to