[PATCH] Android: Fix build for Android
gcc/ * config.gcc: fix target aarch64-linux-android, arm-linux-androideabi, i686-linux-android, x86_64-linux-android * config/linux-android.h: fix SPEC based on aarch64-linux-android-clang * config/aarch64/aarch64-elf.h: Add Macro DEFAULT_ASM_SPEC * config/aarch64/aarch64-linux.h: Add BIONIC_DYNAMIC_LINKER, fix SPEC for aarch64-android * config/aarch64/t-linux-android: New file for aarch64-android muiltarch * config/arm/elf.h: Add Macro DEFAULT_ASM_SPEC * config/arm/linux-eabi.h: Add Macro ASM_SPEC * config/arm/t-linux-androideabi: fix MULTILIB, MULTIARCH * config/gcc/i386/t-linux-android: New file for adding i686-linux-android MULTIARCH * config/gcc/i386/t-linux64-android: New file for adding x86_64-linux-android MULTILIB libgcc/ * config/i386/heap-trampoline.c: Allow x86-android platforms in heap trampolines. libphobos/ * libdruntime/core/stdc/stdio.d: fix stdin,stdout,stderr symbol conflict for android api-level>=23 * libdruntime/gcc/sections/elf.d: for CRuntime_Bionic, SharedELF is true * libdruntime/gcc/sections/package.d: CRuntime_Bionic platform is SectionsElf platform libstdc++-v3/ * config/os/bionic: fix CTYPE undefine --- gcc/config.gcc | 25 +++- gcc/config/aarch64/aarch64-elf.h | 8 +++- gcc/config/aarch64/aarch64-linux.h | 42 ++-- gcc/config/aarch64/t-linux-android | 4 ++ gcc/config/arm/elf.h | 8 +++- gcc/config/arm/linux-eabi.h | 6 +++ gcc/config/arm/t-linux-androideabi | 6 ++- gcc/config/i386/t-linux-android | 1 + gcc/config/i386/t-linux64-android | 3 ++ gcc/config/linux-android.h | 14 +-- libgcc/config/i386/heap-trampoline.c | 2 +- libphobos/libdruntime/core/stdc/stdio.d | 9 +++-- libphobos/libdruntime/gcc/sections/elf.d | 1 + libphobos/libdruntime/gcc/sections/package.d | 1 + libstdc++-v3/config/os/bionic/ctype_base.h | 22 +- 15 files changed, 124 insertions(+), 28 deletions(-) create mode 100644 gcc/config/aarch64/t-linux-android create mode 100644 gcc/config/i386/t-linux-android create mode 100644 gcc/config/i386/t-linux64-android diff --git a/gcc/config.gcc b/gcc/config.gcc index 71ac3badafd..8951567f788 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1241,14 +1241,18 @@ aarch64*-*-netbsd*) extra_options="${extra_options} netbsd.opt netbsd-elf.opt" ;; aarch64*-*-linux*) - tm_file="${tm_file} elfos.h gnu-user.h linux.h glibc-stdint.h" + tm_file="${tm_file} elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h" tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-linux.h" + extra_options="${extra_options} linux-android.opt" tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-linux" tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1" case $target in aarch64_be-*) tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" ;; + *-android) + tmake_file="${tmake_file} aarch64/t-linux-android" + ;; esac aarch64_multilibs="${with_multilib_list}" if test "$aarch64_multilibs" = "default"; then @@ -1476,6 +1480,7 @@ arm*-*-linux-* | arm*-*-uclinuxfdpiceabi) case ${target} in *-androideabi) tmake_file="$tmake_file arm/t-linux-androideabi" + target_cpu_cname="generic-armv7-a" ;; esac # The EABI requires the use of __cxa_atexit. @@ -2022,6 +2027,12 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-gnu* | i[34567]8 tm_file="${tm_file} i386/x86-64.h i386/gnu-user-common.h i386/gnu-user64.h i386/linux-common.h i386/linux64.h" tm_defines="${tm_defines} TARGET_BI_ARCH=1" tmake_file="${tmake_file} i386/t-linux64" + # Define multilib configuration for i686-linux-android. + case ${target} in + *-android) + tmake_file="$tmake_file i386/t-linux64-android" + ;; + esac x86_multilibs="${with_multilib_list}" if test "$x86_multilibs" = "default"; then x86_multilibs="m64,m32" @@ -2085,6 +2096,12 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-gnu*) ;; esac tmake_file="${tmake_file} i386/t-linux64" + # Define multilib configuration for x86_64-linux-android. + case ${target} in + *-android) + tmake_file="$tmake_file i386/t-linux64-android" + ;; + esac x86_multilibs="${with_multilib_list}" if test "$x86_multilibs" = "default"; then case ${with_abi} in @@ -5892,6 +5909,12 @@ case ${target} in i[34567]86-*-linux* | x86_64-*-linux*) extra_objs="${extra_o
Android: Fix build for Android
This is a patch to fix target android 0001-Android-Fix-build-for-Android.patch Description: Binary data
Re: Re: [PATCH] c++/modules: Fix linkage checks for exported using-decls
>On 1/15/25 7:36 PM, yxj-github-437 wrote: >>> On Fri, Jan 03, 2025 at 05:18:55PM +, xxx wrote: >>>> From: yxj-github-437 <2457369...@qq.com> >>>> >>>> This patch attempts to fix an error when build module std. The reason for >>>> the >>>> error is __builrin_va_list (aka struct __va_list) is an internal linkage. >>>> so >>>> attempt to handle this builtin type by identifying whether >>>> DECL_SOURCE_LOCATION (entity) >>>> is BUILTINS_LOCATION. >>>> >>> >>> Hi, thanks for the patch! I suspect this may not be sufficient to >>> completely avoid issues with the __gnuc_va_list type; in particular, if >>> it's internal linkage that may prevent it from being referred to in >>> other ways by inline functions in named modules (due to P1815). >>> >>> Maybe a better approach would be to instead mark this builtin type as >>> TREE_PUBLIC (presumably in aarch64_build_builtin_va_list)? >> >> Thanks, I change my patch to mark TREE_PUBLIC. > > Looks good to me if the ARM maintainers don't object. > > This patch is small enough not to worry about copyright, but > "yxj-github-437 <2457369...@qq.com>" seems like a placeholder name, what > name would you like the commit to use? Thank for your help, and it's my github user name, so just keep it. >> -- >8 -- >> >> This patch attempts to fix an error when build module std. The reason for the >> error is __builtin_va_list (aka struct __va_list) has internal linkage. >> so mark this builtin type as TREE_PUBLIC to make struct __va_list has >> external linkage. >> >> /x/gcc-15.0.0/usr/bin/aarch64-linux-android-g++ -fmodules -std=c++23 -fPIC >> -O2 >> -fsearch-include-path bits/std.cc -c >> /x/gcc-15.0.0/usr/lib/gcc/aarch64-linux-android/15.0.0/include/c++/bits/std.cc:3642:14: >> error: exporting ‘typedef __gnuc_va_list va_list’ that does not have >> external linkage >> 3642 | using std::va_list; >>| ^~~ >> : note: ‘struct __va_list’ declared here with internal linkage >> >> gcc >> * config/aarch64/aarch64.cc (aarch64_build_builtin_va_list): mark >> __builtin_va_list >> as TREE_PUBLIC >> * config/arm/arm.cc (arm_build_builtin_va_list): mark __builtin_va_list >> as TREE_PUBLIC >> * testsuite/g++.dg/modules/builtin-8.C: New test >> --- >> gcc/config/aarch64/aarch64.cc| 1 + >> gcc/config/arm/arm.cc| 1 + >> gcc/testsuite/g++.dg/modules/builtin-8.C | 9 + >> 3 files changed, 11 insertions(+) >> create mode 100644 gcc/testsuite/g++.dg/modules/builtin-8.C >> >> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc >> index ad31e9d255c..e022526e573 100644 >> --- a/gcc/config/aarch64/aarch64.cc >> +++ b/gcc/config/aarch64/aarch64.cc >> @@ -21566,6 +21566,7 @@ aarch64_build_builtin_va_list (void) >> get_identifier ("__va_list"), >> va_list_type); >> DECL_ARTIFICIAL (va_list_name) = 1; >> + TREE_PUBLIC (va_list_name) = 1; >> TYPE_NAME (va_list_type) = va_list_name; >> TYPE_STUB_DECL (va_list_type) = va_list_name; >> >> diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc >> index 1e0791dc8c2..86838ebde5f 100644 >> --- a/gcc/config/arm/arm.cc >> +++ b/gcc/config/arm/arm.cc >> @@ -2906,6 +2906,7 @@ arm_build_builtin_va_list (void) >> get_identifier ("__va_list"), >> va_list_type); >> DECL_ARTIFICIAL (va_list_name) = 1; >> + TREE_PUBLIC (va_list_name) = 1; >> TYPE_NAME (va_list_type) = va_list_name; >> TYPE_STUB_DECL (va_list_type) = va_list_name; >> /* Create the __ap field. */ >> diff --git a/gcc/testsuite/g++.dg/modules/builtin-8.C >> b/gcc/testsuite/g++.dg/modules/builtin-8.C >> new file mode 100644 >> index 000..ff91104e4a9 >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/modules/builtin-8.C >> @@ -0,0 +1,9 @@ >> +// { dg-additional-options -fmodules-ts } >> +module; >> +#include >> +export module builtins; >> +// { dg-module-cmi builtins } >> + >> +export { >> + using ::va_list; >> +}
Re: Re: [PATCH] c++/modules: Fix linkage checks for exported using-decls
> On Fri, Jan 03, 2025 at 05:18:55PM +, xxx wrote: >> From: yxj-github-437 <2457369...@qq.com> >> >> This patch attempts to fix an error when build module std. The reason for the >> error is __builrin_va_list (aka struct __va_list) is an internal linkage. so >> attempt to handle this builtin type by identifying whether >> DECL_SOURCE_LOCATION (entity) >> is BUILTINS_LOCATION. >> > > Hi, thanks for the patch! I suspect this may not be sufficient to > completely avoid issues with the __gnuc_va_list type; in particular, if > it's internal linkage that may prevent it from being referred to in > other ways by inline functions in named modules (due to P1815). > > Maybe a better approach would be to instead mark this builtin type as > TREE_PUBLIC (presumably in aarch64_build_builtin_va_list)? Thanks, I change my patch to mark TREE_PUBLIC. -- >8 -- This patch attempts to fix an error when build module std. The reason for the error is __builtin_va_list (aka struct __va_list) has internal linkage. so mark this builtin type as TREE_PUBLIC to make struct __va_list has external linkage. /x/gcc-15.0.0/usr/bin/aarch64-linux-android-g++ -fmodules -std=c++23 -fPIC -O2 -fsearch-include-path bits/std.cc -c /x/gcc-15.0.0/usr/lib/gcc/aarch64-linux-android/15.0.0/include/c++/bits/std.cc:3642:14: error: exporting ‘typedef __gnuc_va_list va_list’ that does not have external linkage 3642 | using std::va_list; | ^~~ : note: ‘struct __va_list’ declared here with internal linkage gcc * config/aarch64/aarch64.cc (aarch64_build_builtin_va_list): mark __builtin_va_list as TREE_PUBLIC * config/arm/arm.cc (arm_build_builtin_va_list): mark __builtin_va_list as TREE_PUBLIC * testsuite/g++.dg/modules/builtin-8.C: New test --- gcc/config/aarch64/aarch64.cc| 1 + gcc/config/arm/arm.cc| 1 + gcc/testsuite/g++.dg/modules/builtin-8.C | 9 + 3 files changed, 11 insertions(+) create mode 100644 gcc/testsuite/g++.dg/modules/builtin-8.C diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index ad31e9d255c..e022526e573 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -21566,6 +21566,7 @@ aarch64_build_builtin_va_list (void) get_identifier ("__va_list"), va_list_type); DECL_ARTIFICIAL (va_list_name) = 1; + TREE_PUBLIC (va_list_name) = 1; TYPE_NAME (va_list_type) = va_list_name; TYPE_STUB_DECL (va_list_type) = va_list_name; diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 1e0791dc8c2..86838ebde5f 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -2906,6 +2906,7 @@ arm_build_builtin_va_list (void) get_identifier ("__va_list"), va_list_type); DECL_ARTIFICIAL (va_list_name) = 1; + TREE_PUBLIC (va_list_name) = 1; TYPE_NAME (va_list_type) = va_list_name; TYPE_STUB_DECL (va_list_type) = va_list_name; /* Create the __ap field. */ diff --git a/gcc/testsuite/g++.dg/modules/builtin-8.C b/gcc/testsuite/g++.dg/modules/builtin-8.C new file mode 100644 index 000..ff91104e4a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/builtin-8.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules-ts } +module; +#include +export module builtins; +// { dg-module-cmi builtins } + +export { + using ::va_list; +} -- 2.43.0
[PATCH] libstdc++: fix possible undefined std::timespec in module std
I notice std::timespec and std::timespec_get are used in preprocessor condition _GLIBCXX_HAVE_TIMESPEC_GET. So in module std, it should be the same. libstdc++-v3: * src/c++23/std-clib.cc.in: move std::timespec in preprocessor condition _GLIBCXX_HAVE_TIMESPEC_GET --- libstdc++-v3/src/c++23/std-clib.cc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libstdc++-v3/src/c++23/std-clib.cc.in b/libstdc++-v3/src/c++23/std-clib.cc.in index 6809ad229d7..10fc03e7ce0 100644 --- a/libstdc++-v3/src/c++23/std-clib.cc.in +++ b/libstdc++-v3/src/c++23/std-clib.cc.in @@ -585,9 +585,9 @@ export C_LIB_NAMESPACE using std::strftime; using std::time; using std::time_t; - using std::timespec; using std::tm; #ifdef _GLIBCXX_HAVE_TIMESPEC_GET + using std::timespec; using std::timespec_get; #endif } -- 2.43.0
Re: Re: [PATCH] c++/modules: Fix linkage checks for exported using-decls
>On Fri, Jan 03, 2025 at 05:18:55PM +, xxx wrote: >> From: yxj-github-437 <2457369...@qq.com> >> >> This patch attempts to fix an error when build module std. The reason for the >> error is __builrin_va_list (aka struct __va_list) is an internal linkage. so >> attempt to handle this builtin type by identifying whether >> DECL_SOURCE_LOCATION (entity) >> is BUILTINS_LOCATION. >> > >Hi, thanks for the patch! I suspect this may not be sufficient to >completely avoid issues with the __gnuc_va_list type; in particular, if >it's internal linkage that may prevent it from being referred to in >other ways by inline functions in named modules (due to P1815). > >Maybe a better approach would be to instead mark this builtin type as >TREE_PUBLIC (presumably in aarch64_build_builtin_va_list)? Thanks for reply, I notice a function `tree decl_linkage (tree decl)` in cp/tree.cc, which can get a decl's linkage. The type marked with TREE_PUBLIC will return lk_external. Should I add a builtin type also has lk_external?
[PATCH] c++: Fix ICE when template lambdas call with default parameters in unevaluated context
This patch would like to avoid the ICE when template lambdas call with default parameters in unevaluated context. For example as blow: 1 │ template 2 │ void foo(T x) { 3 │ sizeof [](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 [](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 000..a73a1c55a7e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++20 } } + +template +void foo(T x) { + sizeof [](T=x) { return 0; }(); // { dg-error "'x' is not captured" } +}; + +void test() { + foo(0); +} -- 2.43.0
Re: [PATCH] c++: Fix ICE when template lambdas call with default parameters in unevaluated context
>> This patch would like to avoid the ICE when template lambdas call with >> default parameters in unevaluated context. For example as blow: >> >> 1 │ template >> 2 │ void foo(T x) { >> 3 │ sizeof [](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 [](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". > Without the sizeof we get the better error "parameter 'x' cannot appear > in this context"; capturing or not isn't the reason it's ill-formed. > It seems like this code: >> /* Check to see if DECL is a local variable in a context >>where that is forbidden. */ >> if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN) >> && local_variable_p (decl) >> /* DR 2082 permits local variables in unevaluated contexts >>within a default argument. */ >> && !cp_unevaluated_operand) > is confused by the sizeof; I guess we want to cp_evaluated for default > arguments like we do for template arguments. > Jason Thanks, to fix this bug should indeed be handled when lambda parsing. I will make the following modifications. -- >8 -- This patch would like to avoid the ICE when template lambdas call with default parameters in unevaluated context. The bug is the same as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119385. For example as blow: 1 | template 2 | void foo(T x) { 3 | sizeof [](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 [](T=x) { return 0; }(); | ^~ And if without the template code ``, the code will pass compile, it's wrong. When parsing lambda, the sizeof will affect the lambda internal unevaluated operand being handled. So consider save/restore cp_unevaluated_operand. gcc/cp/ChangeLog: * parser.cc (cp_parser_lambda_expression): Save/restore cp_unevaluated_operand when parser lambda. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-uneval25.C: New test. --- gcc/cp/parser.cc | 4 gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C | 11 +++ 2 files changed, 15 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 57a461042bf..9cc51f57fa7 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -11754,6 +11754,8 @@ cp_parser_lambda_expression (cp_parser* parser) /* Inside the class, surrounding template-parameter-lists do not apply. */ unsigned int saved_num_template_parameter_lists = parser->num_template_parameter_lists; +/* Inside the lambda, outside unevaluated context do not apply. */ +int saved_cp_unevaluated_operand = cp_unevaluated_operand; unsigned char in_statement = parser->in_statement; bool in_switch_statement_p = parser->in_switch_statement_p; bool fully_implicit_function_template_p @@ -11765,6 +11767,7 @@ cp_parser_lambda_expression (cp_parser* parser) bool saved_omp_array_section_p = parser->omp_array_section_p; parser->num_template_parameter_lists = 0; +cp_unevaluated_operand = 0; parser->in_statement = 0; parser->in_switch_statement_p = false; parser->fully_implicit_function_template_p = false; @@ -11814,6 +11817,7 @@ cp_parser_lambda_expression (cp_parser* parser) in_discarded_stmt = discarded; parser->num_template_parameter_lists = saved_num_template_parameter_lists; +cp_unevaluated_operand = saved_cp_unevaluated_operand; parser->in_statement = in_statement; parser->in_switch_statement_p = in_switch_statement_p; parser->fully_implicit_function_template_p 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 000..7fdd44d3dd
Re: [PATCH] c++: Fix ICE when template lambdas call with default parameters in unevaluated context
>> This patch would like to avoid the ICE when template lambdas call with >> default parameters in unevaluated context. The bug is the same as >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119385. For example as blow: >> >> 1 | template >> 2 | void foo(T x) { >> 3 | sizeof [](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 [](T=x) { return 0; }(); >>| ^~ >> >> And if without the template code ``, the code will pass compile, it's >> wrong. >> >> When parsing lambda, the sizeof will affect the lambda internal unevaluated >> operand >> being handled. So consider save/restore cp_unevaluated_operand. >> >> gcc/cp/ChangeLog: >> >> * parser.cc (cp_parser_lambda_expression): Save/restore >> cp_unevaluated_operand when parser lambda. >> >> gcc/testsuite/ChangeLog: >> >> * g++.dg/cpp2a/lambda-uneval25.C: New test. >> --- >> gcc/cp/parser.cc | 4 >> gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C | 11 +++ >> 2 files changed, 15 insertions(+) >> create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C >> >> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc >> index 57a461042bf..9cc51f57fa7 100644 >> --- a/gcc/cp/parser.cc >> +++ b/gcc/cp/parser.cc >> @@ -11754,6 +11754,8 @@ cp_parser_lambda_expression (cp_parser* parser) >> /* Inside the class, surrounding template-parameter-lists do not >> apply. */ >> unsigned int saved_num_template_parameter_lists >> = parser->num_template_parameter_lists; >> +/* Inside the lambda, outside unevaluated context do not apply. */ >> +int saved_cp_unevaluated_operand = cp_unevaluated_operand; > Instead of following the surrounding pattern, please use cp_evaluated. > That avoids the need for any change in the other two places. OK, I've replace it with cp_evaluated. >> unsigned char in_statement = parser->in_statement; >> bool in_switch_statement_p = parser->in_switch_statement_p; >> bool fully_implicit_function_template_p >> @@ -11765,6 +11767,7 @@ cp_parser_lambda_expression (cp_parser* parser) >> bool saved_omp_array_section_p = parser->omp_array_section_p; >> >> parser->num_template_parameter_lists = 0; >> +cp_unevaluated_operand = 0; >> parser->in_statement = 0; >> parser->in_switch_statement_p = false; >> parser->fully_implicit_function_template_p = false; >> @@ -11814,6 +11817,7 @@ cp_parser_lambda_expression (cp_parser* parser) >> in_discarded_stmt = discarded; >> >> parser->num_template_parameter_lists = >> saved_num_template_parameter_lists; >> +cp_unevaluated_operand = saved_cp_unevaluated_operand; >> parser->in_statement = in_statement; >> parser->in_switch_statement_p = in_switch_statement_p; >> parser->fully_implicit_function_template_p >> 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 000..7fdd44d3ddd >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval25.C >> @@ -0,0 +1,11 @@ >> +// { dg-do compile { target c++20 } } >> + >> +template >> +void foo(T x) { >> + sizeof [](T=x) { return 0; }(); // { dg-error "may not appear" } >> + sizeof [](T=x) { return 0; }(); // { dg-error "may not appear" } >> +}; >> + >> +void test() { >> + foo(0); >> +} -- >8 -- This patch would like to avoid the ICE when template lambdas call with default parameters in unevaluated context. The bug is the same as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119385. For example as blow: 1 | template 2 | void foo(T x) { 3 | sizeof [](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 [](T=x) { return 0; }(); | ^~ And if without the template code ``, the code will pass compile, it's wrong. When parsing lambda, the sizeof will affect the lambda internal unevaluated operand being handled. So consider save/restore cp_unevaluated_operand. gcc/cp/ChangeLog: * parser.cc (cp_parser_lambda_expression): Use cp_evaluated. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-uneval25.C: New test. --- gcc/cp/pa