[PATCH] Android: Fix build for Android

2024-10-14 Thread yxj-github-437
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

2024-10-11 Thread yxj-github-437
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

2025-01-23 Thread yxj-github-437
>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

2025-01-15 Thread yxj-github-437
> 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

2025-01-16 Thread yxj-github-437
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

2025-01-15 Thread yxj-github-437
>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

2025-03-22 Thread yxj-github-437
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

2025-03-25 Thread yxj-github-437
>> 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

2025-03-25 Thread yxj-github-437
>> 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