This patch would like to avoid the ICE when template lambdas call with default parameters in unevaluated context. For example as blow:
1 │ template <class T> 2 │ void foo(T x) { 3 │ sizeof []<int=0>(T=x) { return 0; }(); 4 │ } 5 │ 6 │ void test { 7 │ foo(0); 8 │ } when compile with -fsyntax-only -std=c++20, it will have ICE similar as below test.cc: In instantiation of ‘void foo(T) [with T = int]’: test.cc:7:6: required from here 6 | foo(0); | ~~~^~~ test.cc:3:38: internal compiler error: in tsubst_expr, at cp/pt.cc:21919 2 | sizeof []<int=0>(T=x) { return 0; }(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ For this example, the template lambda will build with an independent unevaluated context. When convert default arguments, handling `int x` will be in a no unevaluated operand context, the code `gcc_assert (cp_unevaluated_operand)` will make ICE. So just remove this assert, and the code will get an effective error information: "‘x’ is not captured". gcc/cp/ChangeLog: * pt.cc (tsubst_expr): remove cp_unevaluated_operand assert --- gcc/cp/pt.cc | 2 +- gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 538ff220d74..abbf2997a25 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -21916,7 +21916,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* This can happen for a parameter name used later in a function declaration (such as in a late-specified return type). Just make a dummy decl, since it's only used for its type. */ - gcc_assert (cp_unevaluated_operand); + // gcc_assert (cp_unevaluated_operand); r = tsubst_decl (t, args, complain); /* Give it the template pattern as its context; its true context hasn't been instantiated yet and this is good enough for diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C new file mode 100644 index 00000000000..a73a1c55a7e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++20 } } + +template <class T> +void foo(T x) { + sizeof []<int=0>(T=x) { return 0; }(); // { dg-error "'x' is not captured" } +}; + +void test() { + foo(0); +} -- 2.43.0