aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2025-04-09 17:47:34 -0400
committerPatrick Palka <ppalka@redhat.com>2025-04-09 17:47:34 -0400
commitf3862ab07943d1fc6e6a0416657ae4b7d1f3941d (patch)
treed4426a0845a5d79a52abe1007838dc78be3403bd
parent6704d95ec859d9e7480da130bff1e6b58fe37350 (diff)
downloadgcc-f3862ab07943d1fc6e6a0416657ae4b7d1f3941d.zip
gcc-f3862ab07943d1fc6e6a0416657ae4b7d1f3941d.tar.gz
gcc-f3862ab07943d1fc6e6a0416657ae4b7d1f3941d.tar.bz2
c++: ICE with nested default targ lambdas [PR119574]
Here we substitute into the inner lambda twice, first during default argument substitution for the outer template parameters, then during that for the inner template parameters. For the second testcase (which is easier to follow/debug), the first substitution into the inner lambda is with the template arguments {0, NULL_TREE}, which we defer because it's an incremental substitution. For the second and final substitution we have the template arguments {1, NULL_TREE}, which we try combining via add_extra_args and ICE on the checking assert because TREE_STATIC isn't set on the deferred arguments but the template arguments are considered dependent. The template arguments aren't dependent however -- they're just incomplete because when we deferred them we were in the middle of deduction, and we consider a NULL_TREE template argument as dependent. If we remove this checking assert, we go on to correctly merge the template arguments into {{0, NULL_TREE}, {1, NULL_TREE}}. So this patch just removes this imprecise assert. PR c++/119574 gcc/cp/ChangeLog: * pt.cc (add_extra_args): Remove checking assert. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ13.C: New test. * g++.dg/cpp2a/lambda-targ13a.C: New test. * g++.dg/cpp2a/lambda-targ13b.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
-rw-r--r--gcc/cp/pt.cc1
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-targ13.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-targ13a.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C8
4 files changed, 23 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 0e120c4..63c2ec0 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13752,7 +13752,6 @@ add_extra_args (tree extra, tree args, tsubst_flags_t complain, tree in_decl)
gcc_assert (!TREE_PURPOSE (extra));
extra = TREE_VALUE (extra);
}
- gcc_checking_assert (TREE_STATIC (extra) == uses_template_parms (extra));
if (TREE_STATIC (extra))
/* This is a partial substitution into e.g. a requires-expr or lambda-expr
inside a default template argument; we expect 'extra' to be a full set
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 0000000..8fd0a31
--- /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 0000000..8aaefd9
--- /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(); }
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C
new file mode 100644
index 0000000..7f541c7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ13b.C
@@ -0,0 +1,8 @@
+// PR c++/119574
+// A version of lambda-targ13.C where the inner lambda returns non-void.
+// { dg-do compile { target c++20 } }
+
+template <class F = decltype([] <auto G = [] { return 42; }> () { return G(); })>
+constexpr int f(F op = {}) { return op(); }
+
+static_assert(f() == 42);