[gcc r16-381] i386: Fix comment typo on truncsfbf2 pattern

2025-05-05 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:fd2807173a262a954b76e3fdca605c5c8d1788a2

commit r16-381-gfd2807173a262a954b76e3fdca605c5c8d1788a2
Author: Jakub Jelinek 
Date:   Mon May 5 09:17:21 2025 +0200

i386: Fix comment typo on truncsfbf2 pattern

I've noticed a typo on the flag name, fixed thusly.

2025-05-05  Jakub Jelinek  

* config/i386/i386.md (truncsfbf2): Fix comment typo,
unsafte -> unsafe.

Diff:
---
 gcc/config/i386/i386.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 44ee94a3e419..bb02ab0d4e1c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -5704,7 +5704,7 @@
 
 /* vcvtneps2bf16 doesn't honor SNAN, and turn sNAN into qNAN quietly,
and it always round to even.
-   flag_unsafte_math_optimization is needed for psrld.
+   flag_unsafe_math_optimization is needed for psrld.
If we don't expect qNaNs nor sNaNs and can assume rounding
to nearest, we can expand the conversion inline as
(fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16.  */


[gcc r16-382] testsuite/120084 - adjust gcc.dg/lto/pr60779_0.c

2025-05-05 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:7eeb28717b27d5e3786387b35859bbc5d78ed6b6

commit r16-382-g7eeb28717b27d5e3786387b35859bbc5d78ed6b6
Author: Richard Biener 
Date:   Mon May 5 09:14:13 2025 +0200

testsuite/120084 - adjust gcc.dg/lto/pr60779_0.c

Require the linker plugin so functions are properly detected as
unused when inlined.

PR testsuite/120084
* gcc.dg/lto/pr60779_0.c: Require linker-plugin.

Diff:
---
 gcc/testsuite/gcc.dg/lto/pr60779_0.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.dg/lto/pr60779_0.c 
b/gcc/testsuite/gcc.dg/lto/pr60779_0.c
index 360cdc9b51f4..fdeb74c93226 100644
--- a/gcc/testsuite/gcc.dg/lto/pr60779_0.c
+++ b/gcc/testsuite/gcc.dg/lto/pr60779_0.c
@@ -1,4 +1,5 @@
 /* { dg-lto-do link } */
+/* { dg-require-linker-plugin "" } */
 /* { dg-lto-options { { -O -flto -fdump-tree-optimized } } } */
 
 _Complex double bar (_Complex double x, _Complex double y);


[gcc r16-384] 'libgomp.c/interop-hsa.c': GCN offloading only

2025-05-05 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:85ad0d84fcec720c1d94b9bda9a617ced70ba5d2

commit r16-384-g85ad0d84fcec720c1d94b9bda9a617ced70ba5d2
Author: Thomas Schwinge 
Date:   Mon May 5 10:19:30 2025 +0200

'libgomp.c/interop-hsa.c': GCN offloading only

Fix-up for commit 8d84ea28510054fbbb8a2b7441916bd75e29163f
"OpenMP, GCN: Add interop-hsa testcase", which added 
'libgomp.c/interop-hsa.c'.
If nvptx offloading compilation is enabled in addition to GCN, the former 
ICEs:

during RTL pass: final
[...]/libgomp.c/interop-hsa.c: In function 'get_kernel_ptr':
[...]/libgomp.c/interop-hsa.c:34:1: internal compiler error: RTL check: 
expected code 'subreg', have 'reg' in nvptx_print_operand, at 
config/nvptx/nvptx.cc:3082
0x1ccdb96 internal_error(char const*, ...)
[...]/gcc/diagnostic-global-context.cc:517
0x7446c3 rtl_check_failed_code1(rtx_def const*, rtx_code, char const*, 
int, char const*)
[...]/gcc/rtl.cc:770
0x7fa533 nvptx_print_operand
[...]/gcc/config/nvptx/nvptx.cc:3082
0xb25f34 output_operand(rtx_def*, int)
[...]/gcc/final.cc:3641
0xb26f07 output_asm_insn(char const*, rtx_def**)
[...]/gcc/final.cc:3534
0xb29d91 output_asm_insn(char const*, rtx_def**)
[...]/gcc/final.cc:2639
0xb29d91 final_scan_insn_1
[...]/gcc/final.cc:2642
0xb2a59f final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
[...]/gcc/final.cc:2892
0xb2a68c final_1
[...]/gcc/final.cc:1983
0xb2b378 rest_of_handle_final
[...]/gcc/final.cc:4250
0xb2b378 execute
[...]/gcc/final.cc:4328

Regardless of the issue that nvptx offloading compilation probably shouldn't
ICE, the 'asm' insert clearly is valid for GCN only.

libgomp/
* testsuite/libgomp.c/interop-hsa.c: GCN offloading only.

Diff:
---
 libgomp/testsuite/libgomp.c/interop-hsa.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libgomp/testsuite/libgomp.c/interop-hsa.c 
b/libgomp/testsuite/libgomp.c/interop-hsa.c
index cf8bc90bb9c0..21ac91c1b58c 100644
--- a/libgomp/testsuite/libgomp.c/interop-hsa.c
+++ b/libgomp/testsuite/libgomp.c/interop-hsa.c
@@ -1,5 +1,7 @@
 /* { dg-additional-options "-ldl" } */
-/* { dg-require-effective-target offload_device_gcn } */
+/* { dg-require-effective-target offload_device_gcn }
+   The 'asm' insert is valid for GCN only:
+   { dg-additional-options -foffload=amdgcn-amdhsa } */
 
 #include 
 #include 


[gcc r16-385] vect-simd-clone-1[6-8][cd].c: Expect in-branch clones for x86: Fix target selector syntax

2025-05-05 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:c9982eec2d3edc5306291d4628f08825ba46d483

commit r16-385-gc9982eec2d3edc5306291d4628f08825ba46d483
Author: Thomas Schwinge 
Date:   Mon May 5 10:21:35 2025 +0200

vect-simd-clone-1[6-8][cd].c: Expect in-branch clones for x86: Fix target 
selector syntax

Fix-up for commit f9f81d5017adc5d860b24f67aeb89b4e79c7ebdb
"vect-simd-clone-1[6-8][cd].c: Expect in-branch clones for x86", where we 
lost
the relevant testing, for example, for x86_64, or GCN:

 PASS: gcc.dg/vect/vect-simd-clone-16c.c (test for excess errors)
 UNSUPPORTED: gcc.dg/vect/vect-simd-clone-16c.c -flto -ffat-lto-objects
 PASS: gcc.dg/vect/vect-simd-clone-16c.c execution test
-PASS: gcc.dg/vect/vect-simd-clone-16c.c scan-tree-dump-times vect 
"[\\n\\r] [^\\n]* = foo\\.simdclone" 0

 PASS: gcc.dg/vect/vect-simd-clone-16d.c (test for excess errors)
 UNSUPPORTED: gcc.dg/vect/vect-simd-clone-16d.c -flto -ffat-lto-objects
 PASS: gcc.dg/vect/vect-simd-clone-16d.c execution test
-PASS: gcc.dg/vect/vect-simd-clone-16d.c scan-tree-dump-times vect 
"[\\n\\r] [^\\n]* = foo\\.simdclone" 0

 PASS: gcc.dg/vect/vect-simd-clone-17c.c (test for excess errors)
 UNSUPPORTED: gcc.dg/vect/vect-simd-clone-17c.c -flto -ffat-lto-objects
 PASS: gcc.dg/vect/vect-simd-clone-17c.c execution test
-PASS: gcc.dg/vect/vect-simd-clone-17c.c scan-tree-dump-times vect 
"[\\n\\r] [^\\n]* = foo\\.simdclone" 0

 PASS: gcc.dg/vect/vect-simd-clone-17d.c (test for excess errors)
 UNSUPPORTED: gcc.dg/vect/vect-simd-clone-17d.c -flto -ffat-lto-objects
 PASS: gcc.dg/vect/vect-simd-clone-17d.c execution test
-PASS: gcc.dg/vect/vect-simd-clone-17d.c scan-tree-dump-times vect 
"[\\n\\r] [^\\n]* = foo\\.simdclone" 0

 PASS: gcc.dg/vect/vect-simd-clone-18c.c (test for excess errors)
 UNSUPPORTED: gcc.dg/vect/vect-simd-clone-18c.c -flto -ffat-lto-objects
 PASS: gcc.dg/vect/vect-simd-clone-18c.c execution test
-PASS: gcc.dg/vect/vect-simd-clone-18c.c scan-tree-dump-times vect 
"[\\n\\r] [^\\n]* = foo\\.simdclone" 0

 PASS: gcc.dg/vect/vect-simd-clone-18d.c (test for excess errors)
 UNSUPPORTED: gcc.dg/vect/vect-simd-clone-18d.c -flto -ffat-lto-objects
 PASS: gcc.dg/vect/vect-simd-clone-18d.c execution test
-PASS: gcc.dg/vect/vect-simd-clone-18d.c scan-tree-dump-times vect 
"[\\n\\r] [^\\n]* = foo\\.simdclone" 0

..., which this commit restores.

PR middle-end/112877
gcc/testsuite/
* gcc.dg/vect/vect-simd-clone-16c.c: Fix target selector syntax.
* gcc.dg/vect/vect-simd-clone-16d.c: Likewise.
* gcc.dg/vect/vect-simd-clone-17c.c: Likewise.
* gcc.dg/vect/vect-simd-clone-17d.c: Likewise.
* gcc.dg/vect/vect-simd-clone-18c.c: Likewise.
* gcc.dg/vect/vect-simd-clone-18d.c: Likewise.

Diff:
---
 gcc/testsuite/gcc.dg/vect/vect-simd-clone-16c.c | 2 +-
 gcc/testsuite/gcc.dg/vect/vect-simd-clone-16d.c | 2 +-
 gcc/testsuite/gcc.dg/vect/vect-simd-clone-17c.c | 2 +-
 gcc/testsuite/gcc.dg/vect/vect-simd-clone-17d.c | 2 +-
 gcc/testsuite/gcc.dg/vect/vect-simd-clone-18c.c | 2 +-
 gcc/testsuite/gcc.dg/vect/vect-simd-clone-18d.c | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16c.c 
b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16c.c
index 628d45756739..0f7d17393771 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16c.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16c.c
@@ -7,7 +7,7 @@
 
 /* Ensure the the in-branch simd clones are used on targets that support them.
Some targets use another call for the epilogue loops.  */
-/* { dg-final { scan-tree-dump-times {[\n\r] [^\n]* = foo\.simdclone} 2 "vect" 
{ target { !aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump-times {[\n\r] [^\n]* = foo\.simdclone} 2 "vect" 
{ target { ! aarch64*-*-* } } } } */
 /* { dg-final { scan-tree-dump-times {[\n\r] [^\n]* = foo\.simdclone} 3 "vect" 
{ target { aarch64*-*-* } } } } */
 
 /* The LTO test produces two dump files and we scan the wrong one.  */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16d.c 
b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16d.c
index d1f85b0703e9..2127fce0c7e6 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16d.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-clone-16d.c
@@ -7,7 +7,7 @@
 
 /* Ensure the the in-branch simd clones are used on targets that support them.
Some targets use another call for the epilogue loops.  */
-/* { dg-final { scan-tree-dump-times {[\n\r] [^\n]* = foo\.simdclone} 2 "vect" 
{ target { !aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump-times {[\n\r] [^\n]* = foo\.simdclone} 2 "vect" 
{ target { ! aarch64*-*-* } } } } */
 /* { dg-final { scan-tree-dump-times {[\n\r] [^\n]* = foo\.simdclone} 3 "vect" 
{ target { aarch64*-*-

[gcc r16-386] c++: Remove obsolete prototype

2025-05-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:20c2fc676050ebfcd62af50dad08cd2d2736d1e8

commit r16-386-g20c2fc676050ebfcd62af50dad08cd2d2736d1e8
Author: Simon Martin 
Date:   Mon May 5 10:37:52 2025 +0200

c++: Remove obsolete prototype

I noticed while investigating PR c++/119437 that r8-2724-g88b811bd290630
removed parsing_default_capturing_generic_lambda_in_template but not its
prototype in cp-tree.h.

This patch fixes this.

gcc/cp/ChangeLog:

* cp-tree.h (parsing_default_capturing_generic_lambda_in_template):
Remove obsolete prototype.

Diff:
---
 gcc/cp/cp-tree.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index af51d67ef9fe..a42c07a330bc 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7632,7 +7632,6 @@ extern void cp_finish_omp_range_for (tree, tree);
 extern bool cp_maybe_parse_omp_decl (tree, tree);
 extern bool parsing_nsdmi (void);
 extern bool parsing_function_declarator ();
-extern bool parsing_default_capturing_generic_lambda_in_template (void);
 extern void inject_this_parameter (tree, cp_cv_quals);
 extern location_t defparse_location (tree);
 extern void maybe_show_extern_c_location (void);


[gcc r15-9624] libgomp: Update SVE test

2025-05-05 Thread Tejas Belagod via Gcc-cvs
https://gcc.gnu.org/g:941a1b4a00664f23812af00ea56e9795a42a50a4

commit r15-9624-g941a1b4a00664f23812af00ea56e9795a42a50a4
Author: Tejas Belagod 
Date:   Fri Apr 11 10:02:28 2025 +0530

libgomp: Update SVE test

Fix udr-sve.c target test that to check for the correct results based on the
OpenMP clauses used.  The test was first written with a misunderstood
functionality of the reduction clause.

Tested with aarch64-linux-gnu. OK for trunk?

libgomp/ChangeLog:

* testsuite/libgomp.c-target/aarch64/udr-sve.c: Fix test.

Diff:
---
 .../testsuite/libgomp.c-target/aarch64/udr-sve.c   | 58 ++
 1 file changed, 47 insertions(+), 11 deletions(-)

diff --git a/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c 
b/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c
index 03d93cc44b2c..02e02dc04b67 100644
--- a/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c
+++ b/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c
@@ -9,8 +9,8 @@
 void __attribute__ ((noipa))
 parallel_reduction ()
 {
-  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
-  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   svint32_t va = svld1_s32 (svptrue_b32 (), b);
   int i = 0;
   int64_t res;
@@ -30,8 +30,8 @@ parallel_reduction ()
 void __attribute__ ((noipa))
 for_reduction ()
 {
-  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
-  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   svint32_t va = svld1_s32 (svptrue_b32 (), b);
   int j;
   int64_t res;
@@ -58,13 +58,13 @@ simd_reduction ()
   for (j = 0; j < 8; j++)
 a[j] = 1;
 
-  #pragma omp simd reduction (+:va, i)
+  #pragma omp simd reduction (+:va)
   for (j = 0; j < 16; j++)
-va = svld1_s32 (svptrue_b32 (), a);
+va += svld1_s32 (svptrue_b32 (), a);
 
   res = svaddv_s32 (svptrue_b32 (), va);
 
-  if (res != 8)
+  if (res != 128)
 __builtin_abort ();
 }
 
@@ -72,22 +72,57 @@ void __attribute__ ((noipa))
 inscan_reduction_incl ()
 {
   svint32_t va = svindex_s32 (0, 0);
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[64] = { 0 };
   int j;
   int64_t res = 0;
 
-  #pragma omp parallel
-  #pragma omp for reduction (inscan,+:va) firstprivate (res) lastprivate (res)
+  #pragma omp parallel for reduction (inscan, +:va)
   for (j = 0; j < 8; j++)
 {
-  va = svindex_s32 (1, 0);
+  va += svld1_s32 (svptrue_b32 (), a);
   #pragma omp scan inclusive (va)
-  res += svaddv_s32 (svptrue_b32 (), va);
+  svst1_s32 (svptrue_b32 (), b + j * 8, va);
+}
+
+  res = svaddv_s32 (svptrue_b32 (), va);
+
+  if (res != 64)
+__builtin_abort ();
+
+  for (j = 0; j < 64; j+=8)
+if (b[j] != (j / 8 + 1))
+  __builtin_abort ();
+}
+
+void __attribute__ ((noipa))
+inscan_reduction_excl ()
+{
+  svint32_t va = svindex_s32 (0, 0);
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[64] = { 0 };
+  int j;
+  int64_t res = 0;
+
+  #pragma omp parallel for reduction (inscan, +:va)
+  for (j = 0; j < 8; j++)
+{
+  svst1_s32 (svptrue_b32 (), b + j * 8, va);
+  #pragma omp scan exclusive (va)
+  va += svld1_s32 (svptrue_b32 (), a);
 }
 
+  res = svaddv_s32 (svptrue_b32 (), va);
+
   if (res != 64)
 __builtin_abort ();
+
+  for (j = 0; j < 64; j+=8)
+if (b[j] != j / 8)
+  __builtin_abort ();
 }
 
+
 int
 main ()
 {
@@ -95,4 +130,5 @@ main ()
   for_reduction ();
   simd_reduction ();
   inscan_reduction_incl ();
+  inscan_reduction_excl ();
 }


[gcc r16-397] libgomp: Update SVE test

2025-05-05 Thread Tejas Belagod via Gcc-cvs
https://gcc.gnu.org/g:c3979346f963adfdc6c860a43103a0768863cbcf

commit r16-397-gc3979346f963adfdc6c860a43103a0768863cbcf
Author: Tejas Belagod 
Date:   Fri Apr 11 10:02:28 2025 +0530

libgomp: Update SVE test

Fix udr-sve.c target test that to check for the correct results based on the
OpenMP clauses used.  The test was first written with a misunderstood
functionality of the reduction clause.

Tested with aarch64-linux-gnu. OK for trunk?

libgomp/ChangeLog:

* testsuite/libgomp.c-target/aarch64/udr-sve.c: Fix test.

Diff:
---
 .../testsuite/libgomp.c-target/aarch64/udr-sve.c   | 58 ++
 1 file changed, 47 insertions(+), 11 deletions(-)

diff --git a/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c 
b/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c
index 03d93cc44b2c..02e02dc04b67 100644
--- a/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c
+++ b/libgomp/testsuite/libgomp.c-target/aarch64/udr-sve.c
@@ -9,8 +9,8 @@
 void __attribute__ ((noipa))
 parallel_reduction ()
 {
-  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
-  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   svint32_t va = svld1_s32 (svptrue_b32 (), b);
   int i = 0;
   int64_t res;
@@ -30,8 +30,8 @@ parallel_reduction ()
 void __attribute__ ((noipa))
 for_reduction ()
 {
-  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
-  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   svint32_t va = svld1_s32 (svptrue_b32 (), b);
   int j;
   int64_t res;
@@ -58,13 +58,13 @@ simd_reduction ()
   for (j = 0; j < 8; j++)
 a[j] = 1;
 
-  #pragma omp simd reduction (+:va, i)
+  #pragma omp simd reduction (+:va)
   for (j = 0; j < 16; j++)
-va = svld1_s32 (svptrue_b32 (), a);
+va += svld1_s32 (svptrue_b32 (), a);
 
   res = svaddv_s32 (svptrue_b32 (), va);
 
-  if (res != 8)
+  if (res != 128)
 __builtin_abort ();
 }
 
@@ -72,22 +72,57 @@ void __attribute__ ((noipa))
 inscan_reduction_incl ()
 {
   svint32_t va = svindex_s32 (0, 0);
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[64] = { 0 };
   int j;
   int64_t res = 0;
 
-  #pragma omp parallel
-  #pragma omp for reduction (inscan,+:va) firstprivate (res) lastprivate (res)
+  #pragma omp parallel for reduction (inscan, +:va)
   for (j = 0; j < 8; j++)
 {
-  va = svindex_s32 (1, 0);
+  va += svld1_s32 (svptrue_b32 (), a);
   #pragma omp scan inclusive (va)
-  res += svaddv_s32 (svptrue_b32 (), va);
+  svst1_s32 (svptrue_b32 (), b + j * 8, va);
+}
+
+  res = svaddv_s32 (svptrue_b32 (), va);
+
+  if (res != 64)
+__builtin_abort ();
+
+  for (j = 0; j < 64; j+=8)
+if (b[j] != (j / 8 + 1))
+  __builtin_abort ();
+}
+
+void __attribute__ ((noipa))
+inscan_reduction_excl ()
+{
+  svint32_t va = svindex_s32 (0, 0);
+  int a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+  int b[64] = { 0 };
+  int j;
+  int64_t res = 0;
+
+  #pragma omp parallel for reduction (inscan, +:va)
+  for (j = 0; j < 8; j++)
+{
+  svst1_s32 (svptrue_b32 (), b + j * 8, va);
+  #pragma omp scan exclusive (va)
+  va += svld1_s32 (svptrue_b32 (), a);
 }
 
+  res = svaddv_s32 (svptrue_b32 (), va);
+
   if (res != 64)
 __builtin_abort ();
+
+  for (j = 0; j < 64; j+=8)
+if (b[j] != j / 8)
+  __builtin_abort ();
 }
 
+
 int
 main ()
 {
@@ -95,4 +130,5 @@ main ()
   for_reduction ();
   simd_reduction ();
   inscan_reduction_incl ();
+  inscan_reduction_excl ();
 }


[gcc r16-391] Allow IPA_CP to handle UNDEFINED as VARYING.

2025-05-05 Thread Andrew Macleod via Gcc-cvs
https://gcc.gnu.org/g:7f285b7ad7cb89a9b29b52e0d25a7666dc9bd645

commit r16-391-g7f285b7ad7cb89a9b29b52e0d25a7666dc9bd645
Author: Andrew MacLeod 
Date:   Fri May 2 15:48:08 2025 -0400

Allow IPA_CP to handle UNDEFINED as VARYING.

When applying a bitmask to reflect ranges, it is sometimes deferred and
this can result in an UNDEFINED result.  IPA is not expecting this, and
add a check for it, and convert to VARYING if encountered.

PR tree-optimization/120048
gcc/
* ipa-cp.cc (ipcp_store_vr_results): Check for UNDEFINED.

gcc/testsuite/
* gcc.dg/pr120048.c: New.

Diff:
---
 gcc/ipa-cp.cc   | 10 ++
 gcc/testsuite/gcc.dg/pr120048.c | 12 
 2 files changed, 22 insertions(+)

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index f7e5aa9bfd5c..b41148c74de3 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -6362,6 +6362,11 @@ ipcp_store_vr_results (void)
 TYPE_PRECISION (type),
 TYPE_SIGN (type)));
  tmp.update_bitmask (bm);
+ // Reflecting the bitmask on the ranges can sometime
+ // produce an UNDEFINED value if the the bitmask update
+ // was previously deferred.  See PR 120048.
+ if (tmp.undefined_p ())
+   tmp.set_varying (type);
  ipa_vr vr (tmp);
  ts->m_vr->quick_push (vr);
}
@@ -6383,6 +6388,11 @@ ipcp_store_vr_results (void)
 TYPE_PRECISION (type),
 TYPE_SIGN (type)));
  tmp.update_bitmask (bm);
+ // Reflecting the bitmask on the ranges can sometime
+ // produce an UNDEFINED value if the the bitmask update
+ // was previously deferred.  See PR 120048.
+ if (tmp.undefined_p ())
+   tmp.set_varying (type);
  ipa_vr vr (tmp);
  ts->m_vr->quick_push (vr);
}
diff --git a/gcc/testsuite/gcc.dg/pr120048.c b/gcc/testsuite/gcc.dg/pr120048.c
new file mode 100644
index ..6bb34b0e1689
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr120048.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-vrp -fno-tree-fre" } */
+
+int a, b, c;
+static int d(short e) { return e || (a && e) ? 0 : a; }
+static void f(int e) {
+  if (!e) {
+d(0);
+b = d(e);
+  }
+}
+int main() { f(c | 1); }


[gcc r16-389] dwarf2out: Propagate dtprel into the .debug_addr table in resolve_addr_in_expr

2025-05-05 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:662dbe37d9ce479785e6944381d02abb3ecc41db

commit r16-389-g662dbe37d9ce479785e6944381d02abb3ecc41db
Author: Kyle Huey 
Date:   Thu May 1 17:13:47 2025 -0700

dwarf2out: Propagate dtprel into the .debug_addr table in 
resolve_addr_in_expr

For a debugger to display statically-allocated[0] TLS variables the compiler
must communicate information[1] that can be used in conjunction with 
knowledge
of the runtime enviroment[2] to calculate a location for the variable for
each thread. That need gives rise to dw_loc_dtprel in dwarf2out, a flag 
tracking
whether the location description is dtprel, or relative to the
"dynamic thread pointer". Location descriptions in the .debug_info section 
for
TLS variables need to be relocated by the static linker accordingly, and
dw_loc_dtprel controls emission of the needed relocations.

This is further complicated by -gsplit-dwarf. -gsplit-dwarf is designed to 
allow
as much debugging information as possible to bypass the static linker to 
improve
linking performance. One of the ways that is done is by introducing a layer 
of
indirection for relocatable values[3]. That gives rise to addr_index_table 
which
ultimately results in the .debug_addr section.

While the code handling addr_index_table clearly contemplates the existence 
of
dtprel entries[4] resolve_addr_in_expr does not, and the result is that when
using -gsplit-dwarf the DWARF for TLS variables contains an address[5] 
rather
than an offset, and debuggers can't work with that.

This is visible on a trivial example. Compile

```
static __thread int tls_var;

int main(void) {
  tls_var = 42;
  return 0;
}
```

with -g and -g -gsplit-dwarf. Run the program under gdb. When examining the
value of tls_var before and after the assignment, -g behaves as one would
expect but -g -gsplit-dwarf does not. If the user is lucky and the 
miscalculated
address is not mapped, gdb will print "Cannot access memory at address ...".
If the user is unlucky and the miscalculated address is mapped, gdb will 
simply
give the wrong value. You can further confirm that the issue is the address
calculation by asking gdb for the address of tls_var and comparing that to 
what
one would expect.[6]

Thankfully this is trivial to fix by modifying resolve_addr_in_expr to 
propagate
the dtprel character of the location where necessary. gdb begins working as
expected and the diff in the generated assembly is clear.

```
.section.debug_addr,"",@progbits
.long   0x14
.value  0x5
.byte   0x8
.byte   0
 .Ldebug_addr0:
-   .quad   tls_var
+   .long   tls_var@dtpoff, 0
.quad   .LFB0
```

[0] Referring to e.g. __thread as statically-allocated vs. e.g. a
dynamically-allocated pthread_key_create() call.
[1] Generally an offset in a TLS block.
[2] With glibc, provided by libthread_db.so.
[3] Relocatable values are moved to a table in the .debug_addr section, 
those
values in .debug_info are replaced with special values that look up 
indexes
in that table, and then the static linker elsewhere assigns a single 
per-CU
starting index in the .debug_addr section, allowing those special 
values to
remain permanently fixed and the resulting data to be ignored by the 
linker.
[4] ate_kind_rtx_dtprel exists, after all, and new_addr_loc_descr does 
produce
it where appropriate.
[5] e.g. an address in the .tbss/.tdata section.
[6] e.g. on x86-64 by examining %fsbase and the offset in the assembly

2025-05-01  Kyle Huey  

* dwarf2out.cc (resolve_addr_in_expr): Propagate dtprel into the 
address
table when appropriate.

Diff:
---
 gcc/dwarf2out.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 34ffeed86ff1..9aecdb9fd5a1 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -31068,7 +31068,8 @@ resolve_addr_in_expr (dw_attr_node *a, dw_loc_descr_ref 
loc)
   return false;
 remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry);
loc->dw_loc_oprnd1.val_entry
- = add_addr_table_entry (rtl, ate_kind_rtx);
+ = add_addr_table_entry (rtl, loc->dw_loc_dtprel
+ ? ate_kind_rtx_dtprel : ate_kind_rtx);
   }
break;
   case DW_OP_const4u:


[gcc r15-9621] ipa/119973 - IPA PTA issue with global initializers

2025-05-05 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:b36014e10c95d3ada1dcdf4695626af90fba0a99

commit r15-9621-gb36014e10c95d3ada1dcdf4695626af90fba0a99
Author: Richard Biener 
Date:   Mon Apr 28 11:15:53 2025 +0200

ipa/119973 - IPA PTA issue with global initializers

For global initializers with IPA PTA we initialize them from the
IPA reference data but that lacks references to the constant pool.
The following conservatively considers the whole initializer.

PR ipa/119973
* tree-ssa-structalias.cc (create_variable_info_for):
Build constraints from DECL_INITIAL directly rather than
the IPA reference list which is incomplete.

* gcc.dg/torture/pr119973.c: New testcase.

(cherry picked from commit 7a16ef443b13fff9537baa533597836c57131262)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr119973.c | 39 +
 gcc/tree-ssa-structalias.cc | 10 -
 2 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr119973.c 
b/gcc/testsuite/gcc.dg/torture/pr119973.c
new file mode 100644
index ..a9661a3111ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr119973.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fipa-pta" } */
+
+static int
+is_valid_domain_name (const char *string)
+{
+  const char *s;
+
+  for (s=string; *s; s++)
+if (*s == '.')
+  {
+if (string == s)
+  return 0;
+  }
+
+  return !!*string;
+}
+
+int
+main (void)
+{
+  static struct
+  {
+const char *name;
+int valid;
+  } testtbl[] =
+{
+  { ".", 0 },
+  { nullptr, 0 }
+};
+  int idx;
+
+  for (idx=0; testtbl[idx].name; idx++)
+{
+  if (is_valid_domain_name (testtbl[idx].name) != testtbl[idx].valid)
+__builtin_abort ();
+}
+  return 0;
+}
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index d9356a82ad12..f79b54284c64 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -6529,18 +6529,18 @@ create_variable_info_for (tree decl, const char *name, 
bool add_id)
  if (!vnode->all_refs_explicit_p ())
make_copy_constraint (vi, nonlocal_id);
 
- /* If this is a global variable with an initializer and we are in
-IPA mode generate constraints for it.  */
- ipa_ref *ref;
- for (unsigned idx = 0; vnode->iterate_reference (idx, ref); ++idx)
+ /* While we can in theory walk references for the varpool
+node that does not cover zero-initialization or references
+to the constant pool.  */
+ if (DECL_INITIAL (decl))
{
  auto_vec rhsc;
  struct constraint_expr lhs, *rhsp;
  unsigned i;
- get_constraint_for_address_of (ref->referred->decl, &rhsc);
  lhs.var = vi->id;
  lhs.offset = 0;
  lhs.type = SCALAR;
+ get_constraint_for (DECL_INITIAL (decl), &rhsc);
  FOR_EACH_VEC_ELT (rhsc, i, rhsp)
process_constraint (new_constraint (lhs, *rhsp));
  /* If this is a variable that escapes from the unit


[gcc r16-388] testsuite: Link gcc.dg/lto/modref-2_0 with libm

2025-05-05 Thread John David Anglin via Gcc-cvs
https://gcc.gnu.org/g:7fae8dca82abf714a055ff505df51a4c8b43c211

commit r16-388-g7fae8dca82abf714a055ff505df51a4c8b43c211
Author: John David Anglin 
Date:   Mon May 5 09:30:45 2025 -0400

testsuite: Link gcc.dg/lto/modref-2_0 with libm

2025-05-05  John David Anglin  

gcc/testsuite/ChangeLog:

PR testsuite/120085
* gcc.dg/lto/modref-2_0.c: Link test with libm.

Diff:
---
 gcc/testsuite/gcc.dg/lto/modref-2_0.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.dg/lto/modref-2_0.c 
b/gcc/testsuite/gcc.dg/lto/modref-2_0.c
index cf84ed95e775..bba4c8df95ea 100644
--- a/gcc/testsuite/gcc.dg/lto/modref-2_0.c
+++ b/gcc/testsuite/gcc.dg/lto/modref-2_0.c
@@ -1,5 +1,6 @@
 /* { dg-lto-do run } */
 /* { dg-lto-options {"-O2 -flto-partition=max -flto -fno-ipa-sra"}  } */
+/* { dg-extra-ld-options { -lm } } */
 __attribute__ ((noinline))
 void
 test (char *a)


[gcc r16-387] Ada: Fix assertion failure on Finalizable aspect for tagged record type

2025-05-05 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:e67758cd816978a519d751b618043a8957d67e0e

commit r16-387-ge67758cd816978a519d751b618043a8957d67e0e
Author: Eric Botcazou 
Date:   Mon May 5 12:58:58 2025 +0200

Ada: Fix assertion failure on Finalizable aspect for tagged record type

This is a (benign) assertion failure on the mainline for the new Finalizable
aspect put on a tagged record type when not all the primitives are declared.
This compiles and runs on the 15 branch because assertions are disabled.

gcc/ada/
PR ada/120104
* exp_ch3.adb (Expand_Freeze_Record_Type): For a controlled tagged
type, freeze only the controlled primitives that are present.

gcc/testsuite/
* gnat.dg/specs/finalizable1.ads: New test.

Diff:
---
 gcc/ada/exp_ch3.adb  | 30 ++--
 gcc/testsuite/gnat.dg/specs/finalizable1.ads | 11 ++
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 0dfd8102df18..bc46fd37e0c6 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6321,19 +6321,27 @@ package body Exp_Ch3 is
 --  frozen inside.
 
 if Is_Controlled (Typ) then
-   Append_Freeze_Actions (Typ,
- Freeze_Entity
-   (Find_Controlled_Prim_Op (Typ, Name_Initialize), Typ));
+   declare
+  Prim : Entity_Id;
 
-   if not Is_Limited_Type (Typ) then
-  Append_Freeze_Actions (Typ,
-Freeze_Entity
-  (Find_Controlled_Prim_Op (Typ, Name_Adjust), Typ));
-   end if;
+   begin
+  Prim := Find_Controlled_Prim_Op (Typ, Name_Initialize);
+  if Present (Prim) then
+ Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
+  end if;
 
-   Append_Freeze_Actions (Typ,
- Freeze_Entity
-   (Find_Controlled_Prim_Op (Typ, Name_Finalize), Typ));
+  if not Is_Limited_Type (Typ) then
+ Prim := Find_Controlled_Prim_Op (Typ, Name_Adjust);
+ if Present (Prim) then
+Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
+ end if;
+  end if;
+
+  Prim := Find_Controlled_Prim_Op (Typ, Name_Finalize);
+  if Present (Prim) then
+ Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
+  end if;
+   end;
 end if;
 
 --  Freeze rest of primitive operations. There is no need to handle
diff --git a/gcc/testsuite/gnat.dg/specs/finalizable1.ads 
b/gcc/testsuite/gnat.dg/specs/finalizable1.ads
new file mode 100644
index ..5fa8f5cf3c3f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/finalizable1.ads
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+-- { dg-options "-gnatX0" }
+
+package Finalizable1 is
+
+  type Root is abstract tagged null record
+with Finalizable => (Finalize => Finalize);
+
+  procedure Finalize (This : in out Root) is abstract;
+
+end Finalizable1;


[gcc r15-9620] Ada: Fix assertion failure on Finalizable aspect for tagged record type

2025-05-05 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:37c312486186ed9dc2561b2e341fd81f4f1627ec

commit r15-9620-g37c312486186ed9dc2561b2e341fd81f4f1627ec
Author: Eric Botcazou 
Date:   Mon May 5 12:58:58 2025 +0200

Ada: Fix assertion failure on Finalizable aspect for tagged record type

This is a (benign) assertion failure on the mainline for the new Finalizable
aspect put on a tagged record type when not all the primitives are declared.
This compiles and runs on the 15 branch because assertions are disabled.

gcc/ada/
PR ada/120104
* exp_ch3.adb (Expand_Freeze_Record_Type): For a controlled tagged
type, freeze only the controlled primitives that are present.

gcc/testsuite/
* gnat.dg/specs/finalizable1.ads: New test.

Diff:
---
 gcc/ada/exp_ch3.adb  | 30 ++--
 gcc/testsuite/gnat.dg/specs/finalizable1.ads | 11 ++
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 0dfd8102df18..bc46fd37e0c6 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6321,19 +6321,27 @@ package body Exp_Ch3 is
 --  frozen inside.
 
 if Is_Controlled (Typ) then
-   Append_Freeze_Actions (Typ,
- Freeze_Entity
-   (Find_Controlled_Prim_Op (Typ, Name_Initialize), Typ));
+   declare
+  Prim : Entity_Id;
 
-   if not Is_Limited_Type (Typ) then
-  Append_Freeze_Actions (Typ,
-Freeze_Entity
-  (Find_Controlled_Prim_Op (Typ, Name_Adjust), Typ));
-   end if;
+   begin
+  Prim := Find_Controlled_Prim_Op (Typ, Name_Initialize);
+  if Present (Prim) then
+ Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
+  end if;
 
-   Append_Freeze_Actions (Typ,
- Freeze_Entity
-   (Find_Controlled_Prim_Op (Typ, Name_Finalize), Typ));
+  if not Is_Limited_Type (Typ) then
+ Prim := Find_Controlled_Prim_Op (Typ, Name_Adjust);
+ if Present (Prim) then
+Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
+ end if;
+  end if;
+
+  Prim := Find_Controlled_Prim_Op (Typ, Name_Finalize);
+  if Present (Prim) then
+ Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
+  end if;
+   end;
 end if;
 
 --  Freeze rest of primitive operations. There is no need to handle
diff --git a/gcc/testsuite/gnat.dg/specs/finalizable1.ads 
b/gcc/testsuite/gnat.dg/specs/finalizable1.ads
new file mode 100644
index ..5fa8f5cf3c3f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/finalizable1.ads
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+-- { dg-options "-gnatX0" }
+
+package Finalizable1 is
+
+  type Root is abstract tagged null record
+with Finalizable => (Finalize => Finalize);
+
+  procedure Finalize (This : in out Root) is abstract;
+
+end Finalizable1;


[gcc r13-9632] Enable generation of GNU stack notes on Linux

2025-05-05 Thread John David Anglin via Gcc-cvs
https://gcc.gnu.org/g:10b8d94e7f45608dd896c7a780370136ed975c6f

commit r13-9632-g10b8d94e7f45608dd896c7a780370136ed975c6f
Author: John David Anglin 
Date:   Mon Nov 6 20:33:15 2023 +

Enable generation of GNU stack notes on Linux

2023-11-06  John David Anglin  

* config/pa/pa-linux.h (NEED_INDICATE_EXEC_STACK): Define to 1.

Diff:
---
 gcc/config/pa/pa-linux.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/config/pa/pa-linux.h b/gcc/config/pa/pa-linux.h
index d38f68b1fa54..96c54765ddb9 100644
--- a/gcc/config/pa/pa-linux.h
+++ b/gcc/config/pa/pa-linux.h
@@ -144,8 +144,7 @@ along with GCC; see the file COPYING3.  If not see
 #define HAVE_sync_compare_and_swapsi 1
 #define HAVE_sync_compare_and_swapdi 1
 
-/* It's not possible to enable GNU_stack notes since the kernel needs
-   an executable stack for signal returns and syscall restarts.  */
+/* Enable GNU stack notes.  */
 
 #undef NEED_INDICATE_EXEC_STACK
-#define NEED_INDICATE_EXEC_STACK 0
+#define NEED_INDICATE_EXEC_STACK 1


[gcc r12-11087] Enable generation of GNU stack notes on Linux

2025-05-05 Thread John David Anglin via Gcc-cvs
https://gcc.gnu.org/g:8b26ee407613cdbfc3fb2095c09ae28b4642fd63

commit r12-11087-g8b26ee407613cdbfc3fb2095c09ae28b4642fd63
Author: John David Anglin 
Date:   Mon Nov 6 20:33:15 2023 +

Enable generation of GNU stack notes on Linux

2023-11-06  John David Anglin  

* config/pa/pa-linux.h (NEED_INDICATE_EXEC_STACK): Define to 1.

Diff:
---
 gcc/config/pa/pa-linux.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/config/pa/pa-linux.h b/gcc/config/pa/pa-linux.h
index 5af11a1df804..f467d3acbb99 100644
--- a/gcc/config/pa/pa-linux.h
+++ b/gcc/config/pa/pa-linux.h
@@ -147,8 +147,7 @@ along with GCC; see the file COPYING3.  If not see
 #define HAVE_sync_compare_and_swapsi 1
 #define HAVE_sync_compare_and_swapdi 1
 
-/* It's not possible to enable GNU_stack notes since the kernel needs
-   an executable stack for signal returns and syscall restarts.  */
+/* Enable GNU stack notes.  */
 
 #undef NEED_INDICATE_EXEC_STACK
-#define NEED_INDICATE_EXEC_STACK 0
+#define NEED_INDICATE_EXEC_STACK 1


[gcc r16-383] c++: Inhibit subsequent warnings/notes in diagnostic_groups with an inhibited warning [PR118163, PR11

2025-05-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:0f1d55a75b09c13e3db09654c2b5aaad5741262f

commit r16-383-g0f1d55a75b09c13e3db09654c2b5aaad5741262f
Author: Simon Martin 
Date:   Mon May 5 10:12:08 2025 +0200

c++: Inhibit subsequent warnings/notes in diagnostic_groups with an 
inhibited warning [PR118163,PR118392]

Those 2 PRs show that even when using a *single* diagnostic_group, it's
possible to end up with a warning being inhibited and its associated
note still emitted, which leads to puzzling user experience. Example
from PR118392:

===
$ gcc/cc1plus inhibit-warn-3.C -w
inhibit-warn-3.C:10:17: note: only here as a ‘friend’
   10 | friend void bar();
  | ^~~
===

Following a suggestion from ppalka@, this patch keeps track of the
"diagnostic depth" at which a warning in inhibited, and makes sure that
all subsequent notes at that depth or deeper are inhibited as well,
until a subsequent warning or error is accepted at that depth, or the
diagnostic_group or nesting level is popped.

PR c++/118163
PR c++/118392

gcc/ChangeLog:

* diagnostic.cc (diagnostic_context::initialize): Initialize
m_diagnostic_groups.m_inhibiting_notes_from.
(diagnostic_context::inhibit_notes_in_group): New.
(diagnostic_context::notes_inhibited_in_group): New
(diagnostic_context::report_diagnostic): Call
inhibit_notes_in_group and notes_inhibited_in_group.
(diagnostic_context::end_group): Call inhibit_notes_in_group.
(diagnostic_context::pop_nesting_level): Ditto.
* diagnostic.h (diagnostic_context::m_diagnostic_groups): Add
member to track the depth at which a warning has been inhibited.
(diagnostic_context::notes_inhibited_in_group): Declare.
(diagnostic_context::inhibit_notes_in_group): Declare.
* doc/ux.texi: Document diagnostic_group behavior with regards
to inhibited warnings.

gcc/testsuite/ChangeLog:

* g++.dg/diagnostic/incomplete-type-2.C: New test.
* g++.dg/diagnostic/incomplete-type-2a.C: New test.
* g++.dg/diagnostic/inhibit-warn-3.C: New test.

Diff:
---
 gcc/diagnostic.cc  | 67 +-
 gcc/diagnostic.h   |  6 ++
 gcc/doc/ux.texi|  5 +-
 .../g++.dg/diagnostic/incomplete-type-2.C  |  7 +++
 .../g++.dg/diagnostic/incomplete-type-2a.C | 13 +
 gcc/testsuite/g++.dg/diagnostic/inhibit-warn-3.C   | 15 +
 6 files changed, 110 insertions(+), 3 deletions(-)

diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 429c4b1b116a..c3ea1b34d2f2 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -282,6 +282,7 @@ diagnostic_context::initialize (int n_opts)
   m_diagnostic_groups.m_group_nesting_depth = 0;
   m_diagnostic_groups.m_diagnostic_nesting_level = 0;
   m_diagnostic_groups.m_emission_count = 0;
+  m_diagnostic_groups.m_inhibiting_notes_from = 0;
   m_output_sinks.safe_push
 (new diagnostic_text_output_format (*this, nullptr, true));
   m_set_locations_cb = nullptr;
@@ -917,6 +918,7 @@ diagnostic_context::check_max_errors (bool flush)
 
 /* Take any action which is expected to happen after the diagnostic
is written out.  This function does not always return.  */
+
 void
 diagnostic_context::action_after_output (diagnostic_t diag_kind)
 {
@@ -991,6 +993,50 @@ diagnostic_context::action_after_output (diagnostic_t 
diag_kind)
 }
 }
 
+/* State whether we should inhibit notes in the current diagnostic_group and
+   its future children if any.  */
+
+void
+diagnostic_context::inhibit_notes_in_group (bool inhibit)
+{
+  int curr_depth = (m_diagnostic_groups.m_group_nesting_depth
+   + m_diagnostic_groups.m_diagnostic_nesting_level);
+
+  if (inhibit)
+{
+  /* If we're already inhibiting, there's nothing to do.  */
+  if (m_diagnostic_groups.m_inhibiting_notes_from)
+   return;
+
+  /* Since we're called via warning/error/... that all have their own
+diagnostic_group, we must consider that we started inhibiting in their
+parent.  */
+  gcc_assert (m_diagnostic_groups.m_group_nesting_depth > 0);
+  m_diagnostic_groups.m_inhibiting_notes_from = curr_depth - 1;
+}
+  else if (m_diagnostic_groups.m_inhibiting_notes_from)
+{
+  /* Only cancel inhibition at the depth that set it up.  */
+  if (curr_depth >= m_diagnostic_groups.m_inhibiting_notes_from)
+   return;
+
+  m_diagnostic_groups.m_inhibiting_notes_from = 0;
+}
+}
+
+/* Return whether notes must be inhibited in the current diagnostic_group.  */
+
+bool
+diagnostic_context::notes_inhibited_in_group () const
+{
+  if (m_diagnostic_groups.m_inhibiting_notes_from
+  && (m_diagnostic_groups.m_group_nesting_depth
+ 

[gcc r14-11735] c++/coro: prevent ICV_STATEMENT diagnostics in temp promotion [PR116502]

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:694b942a179f5fbaee882a5e619e5bbaf64b4d11

commit r14-11735-g694b942a179f5fbaee882a5e619e5bbaf64b4d11
Author: Arsen Arsenović 
Date:   Wed Aug 28 21:59:18 2024 +0200

c++/coro: prevent ICV_STATEMENT diagnostics in temp promotion [PR116502]

If such a diagnostic is necessary, it has already been emitted,
otherwise, it is not correct and emitting it here is inactionable by the
user, and bogus.

PR c++/116502

gcc/cp/ChangeLog:

* coroutines.cc (maybe_promote_temps): Convert temporary
initializers to void without complaining.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/maybe-unused-1.C: New test.
* g++.dg/coroutines/pr116502.C: New test.

(cherry picked from commit 05e4f07cad1eacf869c10622cae2a9cdee3b6a7a)

Diff:
---
 gcc/cp/coroutines.cc | 12 ++---
 gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C | 33 
 gcc/testsuite/g++.dg/coroutines/pr116502.C   | 33 
 3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index e0e312265c10..de160bad1a20 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3323,7 +3323,13 @@ maybe_promote_temps (tree *stmt, void *d)
 to run the initializer.
 If the initializer is a conditional expression, we need to collect
 and declare any promoted variables nested within it.  DTORs for such
-variables must be run conditionally too.  */
+variables must be run conditionally too.
+
+Since here we're synthetically processing code here, we've already
+emitted any Wunused-result warnings.  Below, however, we call
+finish_expr_stmt, which will convert its operand to void, and could
+result in such a diagnostic being emitted.  To avoid that, convert to
+void ahead of time.  */
   if (t->var)
{
  tree var = t->var;
@@ -,7 +3339,7 @@ maybe_promote_temps (tree *stmt, void *d)
  if (TREE_CODE (t->init) == COND_EXPR)
process_conditional (t, vlist);
  else
-   finish_expr_stmt (t->init);
+   finish_expr_stmt (convert_to_void (t->init, ICV_STATEMENT, 
tf_none));
  if (tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error))
{
  tree cl = build_stmt (sloc, CLEANUP_STMT, expr_list, cleanup, 
var);
@@ -3352,7 +3358,7 @@ maybe_promote_temps (tree *stmt, void *d)
  if (TREE_CODE (t->init) == COND_EXPR)
process_conditional (t, vlist);
  else
-   finish_expr_stmt (t->init);
+   finish_expr_stmt (convert_to_void (t->init, ICV_STATEMENT, 
tf_none));
  if (expr_list)
{
  if (TREE_CODE (expr_list) != STATEMENT_LIST)
diff --git a/gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C 
b/gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C
new file mode 100644
index ..68d59d83e8eb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C
@@ -0,0 +1,33 @@
+// https://gcc.gnu.org/PR116502
+#include 
+
+struct SuspendNever {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coroutine;
+
+struct PromiseType {
+  Coroutine get_return_object();
+  SuspendNever initial_suspend();
+  SuspendNever final_suspend() noexcept;
+  void return_void();
+  void unhandled_exception();
+};
+
+struct Coroutine {
+  using promise_type = PromiseType;
+};
+
+struct Awaiter {
+  bool await_ready();
+  void await_suspend(std::coroutine_handle<>);
+  [[nodiscard]] int& await_resume();
+};
+
+Coroutine foo()
+{
+  co_await Awaiter {}; // { dg-warning "Wunused-result" }
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr116502.C 
b/gcc/testsuite/g++.dg/coroutines/pr116502.C
new file mode 100644
index ..95cc0bc8a983
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr116502.C
@@ -0,0 +1,33 @@
+// https://gcc.gnu.org/PR116502
+#include 
+
+struct SuspendNever {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coroutine;
+
+struct PromiseType {
+  Coroutine get_return_object();
+  SuspendNever initial_suspend();
+  SuspendNever final_suspend() noexcept;
+  void return_void();
+  void unhandled_exception();
+};
+
+struct Coroutine {
+  using promise_type = PromiseType;
+};
+
+struct Awaiter {
+  bool await_ready();
+  void await_suspend(std::coroutine_handle<>);
+  [[nodiscard]] int& await_resume();
+};
+
+Coroutine foo()
+{
+  (void)co_await Awaiter {};
+}


[gcc r14-11736] c++: simplify handling implicit INDIRECT_REF and co_await in convert_to_void

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:0ff545dbc2fd6ffa6ae544c3754ecaa7f9864a22

commit r14-11736-g0ff545dbc2fd6ffa6ae544c3754ecaa7f9864a22
Author: Arsen Arsenović 
Date:   Fri Sep 20 13:13:02 2024 +0200

c++: simplify handling implicit INDIRECT_REF and co_await in convert_to_void

convert_to_void has, so far, when converting a co_await expression to
void altered the await_resume expression of a co_await so that it is
also converted to void.  This meant that the type of the await_resume
expression, which is also supposed to be the type of the whole co_await
expression, was not the same as the type of the CO_AWAIT_EXPR tree.

While this has not caused problems so far, it is unexpected, I think.

Also, convert_to_void had a special case when an INDIRECT_REF wrapped a
CALL_EXPR.  In this case, we also diagnosed maybe_warn_nodiscard.  This
was a duplication of logic related to converting call expressions to
void.

Instead, we can generalize a bit, and rather discard the expression that
was implicitly dereferenced instead.

This patch changes the diagnostic of:

  void f(struct S* x) { static_cast(*x); }

... from:

  warning: indirection will not access object of incomplete type
   'volatile S' in statement

... to:

  warning: implicit dereference will not access object of type
   ‘volatile S’ in statement

... but should have no impact in other cases.

gcc/cp/ChangeLog:

* coroutines.cc (co_await_get_resume_call): Return a tree
directly, rather than a tree pointer.
* cp-tree.h (co_await_get_resume_call): Adjust signature
accordingly.
* cvt.cc (convert_to_void): Do not alter CO_AWAIT_EXPRs when
discarding them.  Simplify handling implicit INDIRECT_REFs.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/nodiscard-1.C: New test.

(cherry picked from commit de03ef6337b0a368d61c74b790313b4216c7ed6e)

Diff:
---
 gcc/cp/coroutines.cc  | 12 
 gcc/cp/cp-tree.h  |  2 +
 gcc/cp/cvt.cc | 98 +++
 gcc/testsuite/g++.dg/coroutines/nodiscard-1.C | 77 +
 4 files changed, 145 insertions(+), 44 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index de160bad1a20..3872e96b7429 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -725,6 +725,18 @@ coro_get_destroy_function (tree decl)
   return NULL_TREE;
 }
 
+/* Given a CO_AWAIT_EXPR AWAIT_EXPR, return its resume call.  */
+
+tree
+co_await_get_resume_call (tree await_expr)
+{
+  gcc_checking_assert (TREE_CODE (await_expr) == CO_AWAIT_EXPR);
+  tree vec = TREE_OPERAND (await_expr, 3);
+  if (!vec)
+return nullptr;
+  return TREE_VEC_ELT (vec, 2);
+}
+
 /* These functions assumes that the caller has verified that the state for
the decl has been initialized, we try to minimize work here.  */
 
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 19e7b2edede3..1d10c27c676c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8767,6 +8767,8 @@ extern tree coro_get_actor_function   (tree);
 extern tree coro_get_destroy_function  (tree);
 extern tree coro_get_ramp_function (tree);
 
+extern tree co_await_get_resume_call   (tree await_expr);
+
 /* contracts.cc */
 extern tree make_postcondition_variable(cp_expr);
 extern tree make_postcondition_variable(cp_expr, tree);
diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index b046010e7ff8..dac210d12479 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -1285,88 +1285,96 @@ convert_to_void (tree expr, impl_conv_void implicit, 
tsubst_flags_t complain)
  complete_type (type);
int is_complete = COMPLETE_TYPE_P (type);
 
-   /* Can't load the value if we don't know the type.  */
-   if (is_volatile && !is_complete)
+   /* Don't load the value if this is an implicit dereference, or if
+  the type needs to be handled by ctors/dtors.  */
+   if (is_reference)
   {
-if (complain & tf_warning)
+if (is_volatile && (complain & tf_warning)
+   /* A co_await expression, in its await_resume expression, also
+  contains an implicit dereference.  As a result, we don't
+  need to warn about them here.  */
+   && TREE_CODE (TREE_OPERAND (expr, 0)) != CO_AWAIT_EXPR)
  switch (implicit)
{
  case ICV_CAST:
warning_at (loc, 0, "conversion to void will not access "
-   "object of incomplete type %qT", type);
+   "object of type %qT", type);
break;
  case ICV_SECOND_OF_COND:
-   warning_at

[gcc r14-11739] c++: fix conversion issues

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:b6094031eea96c116a386e7112ee79a6bde5207e

commit r14-11739-gb6094031eea96c116a386e7112ee79a6bde5207e
Author: Jason Merrill 
Date:   Mon Dec 23 19:57:56 2024 -0500

c++: fix conversion issues

back-port the coroutine part of this.

Some issues caught by a check from another patch:

In build_ramp_function, we're assigning REFERENCE_TYPE things, so we need to
build the assignment directly rather than rely on functions that implement
C++ semantics.

gcc/cp/ChangeLog:

* coroutines.cc (cp_coroutine_transform::build_ramp_function): Build
INIT_EXPR directly.

(cherry picked from commit dd3f3c71df66ed6fd3872ab780f5813831100d1c)

Diff:
---
 gcc/cp/coroutines.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 77067be45ad4..09e2f3410627 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -5093,8 +5093,8 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
 
  if (parm.rv_ref || parm.pt_ref)
/* Initialise the frame reference field directly.  */
-   r = cp_build_modify_expr (fn_start, TREE_OPERAND (fld_idx, 0),
- INIT_EXPR, arg, tf_warning_or_error);
+   r = build2 (INIT_EXPR, TREE_TYPE (arg),
+   TREE_OPERAND (fld_idx, 0), arg);
  else
{
  r = forward_parm (arg);


[gcc r16-394] [RISC-V][PR target/119971] Avoid losing shift count masking

2025-05-05 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:05d75c5bfcf923bc0258b79a08c5861590c5a2b9

commit r16-394-g05d75c5bfcf923bc0258b79a08c5861590c5a2b9
Author: Jeff Law 
Date:   Mon May 5 17:14:29 2025 -0600

[RISC-V][PR target/119971] Avoid losing shift count masking

As is outlined in the PR, we have a few define_insn_and_split patterns which
optimize away explicit masking of shift/bit positions when the masking 
matches
what the hardware's behavior.

A small number of those define_insn_and_split patterns generate a single
instruction.  It's fairly elegant in that we were essentially just rewriting
the RTL to match an existing pattern.

In one case we'd do the rewriting and later turn a 32bit shift into a bset.
That's not safe because the masking of a 32bit shift uses 0x1f while 
masking on
bset uses 0x3f on rv64.   The net was incorrect code as seen in the BZ 
entry.

The fix is pretty simple.  There's no real reason we need to use a
define_insn_and_split.  It was just convenient.  Instead we can use a simple
define_insn.  That avoids a change in the masking behavior for the shift
count/bit position and the masking stays in the RTL.

I quickly scanned the entire port and didn't see any additional
define_insn_and_splits that obviously generated a single instruction outside
the shift/rotate space, though in the vector space that's nontrivial to
ascertain.

This was been run through my tester for the cross configurations, but not 
the
native bootstrap/regression test (yet).

PR target/119971
gcc/
* config/riscv/bitmanip.md (rotation with masked count): Rewrite
as define_insn patterns.  Fix formatting.
* config/riscv/riscv.md (shift with masked count): Similarly.

gcc/testsuite
* gcc.target/riscv/pr119971.c: New test.
* gcc.target/riscv/zbb-rol-ror-03.c: Adjust test slightly.

Diff:
---
 gcc/config/riscv/bitmanip.md| 59 +
 gcc/config/riscv/riscv.md   | 19 ++--
 gcc/testsuite/gcc.target/riscv/pr119971.c   | 24 ++
 gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c |  2 +-
 4 files changed, 59 insertions(+), 45 deletions(-)

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index d0919ece31f7..20d03dc8792d 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -423,39 +423,40 @@
   "rolw\t%0,%1,%2"
   [(set_attr "type" "bitmanip")])
 
-(define_insn_and_split "*3_mask"
-  [(set (match_operand:GPR 0 "register_operand" "= r")
-(bitmanip_rotate:GPR
-(match_operand:GPR 1 "register_operand" "  r")
-(match_operator 4 "subreg_lowpart_operator"
- [(and:GPR2
-   (match_operand:GPR2 2 "register_operand"  "r")
-   (match_operand 3 "" ""))])))]
+(define_insn "*3_mask"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (bitmanip_rotate:X
+ (match_operand:X 1 "register_operand" "r")
+ (match_operator 4 "subreg_lowpart_operator"
+   [(and:X (match_operand:X 2 "register_operand"  "r")
+   (match_operand 3 "" ""))])))]
   "TARGET_ZBB || TARGET_ZBKB"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-(bitmanip_rotate:GPR (match_dup 1)
- (match_dup 2)))]
-  "operands[2] = gen_lowpart (QImode, operands[2]);"
+  "\t%0,%1,%2"
   [(set_attr "type" "bitmanip")
-   (set_attr "mode" "")])
+   (set_attr "mode" "")])
 
-(define_insn_and_split "*si3_sext_mask"
-  [(set (match_operand:DI 0 "register_operand" "= r")
-  (sign_extend:DI (bitmanip_rotate:SI
-(match_operand:SI 1 "register_operand" "  r")
-(match_operator 4 "subreg_lowpart_operator"
- [(and:GPR
-   (match_operand:GPR 2 "register_operand"  "r")
-   (match_operand 3 "const_si_mask_operand"))]]
+(define_insn "*3_mask_si"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (bitmanip_rotate:SI
+ (match_operand:SI 1 "register_operand" "r")
+ (match_operator 3 "subreg_lowpart_operator"
+   [(and:X (match_operand:SI 2 "register_operand"  "r")
+   (const_int 31))])))]
   "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-  (sign_extend:DI (bitmanip_rotate:SI (match_dup 1)
-   (match_dup 2]
-  "operands[2] = gen_lowpart (QImode, operands[2]);"
+  "w\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "SI")])
+
+(define_insn "*si3_sext_mask"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI
+ (bitmanip_rotate:SI
+   (match_operand:SI 1 "register_operand" "r")
+   (match_operator 3 "subreg_lowpart_operator"
+ [(and:X (match_operand:GPR 2 "register_operand"  "r")
+ (const_int 31))]]
+  "T

[gcc r14-11733] c++, coroutines: Fix handling of bool await_suspend() [PR115905].

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:eb600ecb6af628e492fb86dee50cda049ac708e3

commit r14-11733-geb600ecb6af628e492fb86dee50cda049ac708e3
Author: Iain Sandoe 
Date:   Fri Sep 6 20:59:43 2024 +0100

c++, coroutines: Fix handling of bool await_suspend() [PR115905].

As noted in the PR the action of the existing implementation was to
treat a false value from await_suspend () as equivalent to "do not
suspend".  Actually it needs to be the equivalent of "resume" - and
we need to restart the dispatcher - since the await_suspend() body
could have already resumed the coroutine.
See also https://github.com/cplusplus/CWG/issues/601 (NAD) for more
discussion.

Since we need to amend the await expansion and the actor build, take
the opportunity to clean up and modernise the code there.  Note that
we need to make the jump back to the dispatcher without any scope
exit cleanups (so we have to use the .CO_SUSPN IFN to do this).

PR c++/115905

gcc/cp/ChangeLog:

* coroutines.cc (struct coro_aw_data): Add a member for the
restart dispatch label.
(expand_one_await_expression): Rework to modernise and to
handle the boolean await_suspend() case.
(build_actor_fn): Rework the dispatcher and allow for a jump
back to the dispatcher.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/torture/pr115905.C: New test.

Signed-off-by: Iain Sandoe 
(cherry picked from commit 368ba7aed46d57d093c0180baae4dc0e0ba468b6)

Diff:
---
 gcc/cp/coroutines.cc   | 219 +++--
 gcc/testsuite/g++.dg/coroutines/torture/pr115905.C |  64 ++
 2 files changed, 176 insertions(+), 107 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 8bb46ff5c990..4b13f904ff0e 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1791,6 +1791,7 @@ struct coro_aw_data
   tree cleanup;/* This is where to go once we complete local destroy.  */
   tree cororet;/* This is where to go if we suspend.  */
   tree corocont;   /* This is where to go if we continue.  */
+  tree dispatch;   /* This is where we go if we restart the dispatch.  */
   tree conthand;   /* This is the handle for a continuation.  */
   unsigned index;  /* This is our current resume index.  */
 };
@@ -1835,42 +1836,44 @@ co_await_find_in_subtree (tree *stmt, int *, void *d)
in either.  */
 
 static tree *
-expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
+expand_one_await_expression (tree *expr, tree *await_expr, void *d)
 {
   coro_aw_data *data = (coro_aw_data *) d;
 
-  tree saved_statement = *stmt;
+  tree saved_statement = *expr;
   tree saved_co_await = *await_expr;
 
   tree actor = data->actor_fn;
-  location_t loc = EXPR_LOCATION (*stmt);
+  location_t loc = EXPR_LOCATION (*expr);
   tree var = TREE_OPERAND (saved_co_await, 1);  /* frame slot. */
-  tree expr = TREE_OPERAND (saved_co_await, 2); /* initializer.  */
+  tree init_expr = TREE_OPERAND (saved_co_await, 2); /* initializer.  */
   tree awaiter_calls = TREE_OPERAND (saved_co_await, 3);
 
   tree source = TREE_OPERAND (saved_co_await, 4);
   bool is_final = (source
   && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT);
-  bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
+
+  /* Build labels for the destinations of the control flow when we are resuming
+ or destroying.  */
   int resume_point = data->index;
-  size_t bufsize = sizeof ("destroy.") + 10;
-  char *buf = (char *) alloca (bufsize);
-  snprintf (buf, bufsize, "destroy.%d", resume_point);
+  char *buf = xasprintf ("destroy.%d", resume_point);
   tree destroy_label = create_named_label_with_ctx (loc, buf, actor);
-  snprintf (buf, bufsize, "resume.%d", resume_point);
+  free (buf);
+  buf = xasprintf ("resume.%d", resume_point);
   tree resume_label = create_named_label_with_ctx (loc, buf, actor);
-  tree empty_list = build_empty_stmt (loc);
+  free (buf);
 
-  tree stmt_list = NULL;
-  tree r;
+  /* This will contain our expanded expression and replace the original
+ expression.  */
+  tree stmt_list = push_stmt_list ();
   tree *await_init = NULL;
 
-  if (!expr)
+  bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
+  if (!init_expr)
 needs_dtor = false; /* No need, the var's lifetime is managed elsewhere.  
*/
   else
 {
-  r = coro_build_cvt_void_expr_stmt (expr, loc);
-  append_to_statement_list_force (r, &stmt_list);
+  finish_expr_stmt (init_expr);
   /* We have an initializer, which might itself contain await exprs.  */
   await_init = tsi_stmt_ptr (tsi_last (stmt_list));
 }
@@ -1881,18 +1884,15 @@ expand_one_await_expression (tree *stmt, tree 
*await_expr, void *d)
   if (TREE_CODE (TREE_TYPE (ready_cond)) != BOOLEAN_TYPE)
 ready_cond = cp_convert (boolean_type_node, ready_cond,
  

[gcc r16-396] libphobos: enable for sparc64-unknown-linux-gnu

2025-05-05 Thread Sam James via Gcc-cvs
https://gcc.gnu.org/g:2572d46f0d1e426c1091f9b84861ee5213b84b5a

commit r16-396-g2572d46f0d1e426c1091f9b84861ee5213b84b5a
Author: Sam James 
Date:   Sun Apr 20 01:43:39 2025 +0100

libphobos: enable for sparc64-unknown-linux-gnu

This bootstraps with some test failures but works well enough to build
11..15.

libphobos/ChangeLog:

* configure.tgt: Add sparc64-unknown-linux-gnu as a supported 
target.

Diff:
---
 libphobos/configure.tgt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libphobos/configure.tgt b/libphobos/configure.tgt
index b32300b52a18..76c09c4640dd 100644
--- a/libphobos/configure.tgt
+++ b/libphobos/configure.tgt
@@ -58,7 +58,7 @@ case "${target}" in
   s390*-linux*)
LIBPHOBOS_SUPPORTED=yes
;;
-  sparc*-*-solaris2.11*)
+  sparc64-*-linux* | sparc*-*-solaris2.11*)
LIBPHOBOS_SUPPORTED=yes
;;
   *-*-darwin9* | *-*-darwin1[01]*)


[gcc r14-11734] c++, coroutines: Revise promise construction/destruction.

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:5dbf5f9f4f83b0048e7c3af8fbaefb503d56928e

commit r14-11734-g5dbf5f9f4f83b0048e7c3af8fbaefb503d56928e
Author: Iain Sandoe 
Date:   Sat Aug 31 13:08:42 2024 +0100

c++, coroutines: Revise promise construction/destruction.

In examining the coroutine testcases for unexpected diagnostic output
for 'Wall', I found a 'statement has no effect' warning for the promise
construction in one case.  In particular, the case is where the users
promise type has an implicit CTOR but a user-provided DTOR. Further, the
type does not actually need constructing.

In very early versions of the coroutines code we used to check
TYPE_NEEDS_CONSTRUCTING() to determine whether to attempt to build
a constructor call for the promise.  During review, it was suggested
to use type_build_ctor_call () instead.

This latter call checks the constructors in the type (both user-defined
and implicit) and returns true, amongst other cases if any of the found
CTORs are marked as deprecated.

In a number of places (for example [class.copy.ctor] / 6) the standard
says that some version of an implicit CTOR is deprecated when the user
provides a DTOR.

Thus, for this specific arrangement of promise type, type_build_ctor_call
returns true, because of (for example) a deprecated implicit copy CTOR.

We are not going to use any of the deprecated CTORs and thus will not
see warnings from this - however, since the call returned true, we have
now determined that we should attempt to build a constructor call.

Note as above, the type does not actually require construction and thus
one might expect either a NULL_TREE or error_mark_node in response to
the build_special_member_call ().  However, in practice the function
returns the original instance object instead of a call or some error.

When we add that as a statement it triggers the 'statement has no effect'
warning.

The patch here rearranges the promise construction/destruction code to
allow for the case that a DTOR is required independently of a CTOR. In
addition, we check that the return from build_special_member_call ()
has side effects before we add it as a statement.

gcc/cp/ChangeLog:

* coroutines.cc
(cp_coroutine_transform::build_ramp_function): Separate the
build of promise constructor and destructor.  When evaluating
the constructor, check that build_special_member_call returns
an expression with side effects before adding it.

Signed-off-by: Iain Sandoe 
(cherry picked from commit 7d1483921941d21d91f929ef0d59a9794b1946b4)

Diff:
---
 gcc/cp/coroutines.cc | 31 +--
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 4b13f904ff0e..e0e312265c10 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -5108,16 +5108,12 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE,
   false, tf_warning_or_error);
 
-  tree promise_dtor = NULL_TREE;
   if (type_build_ctor_call (promise_type))
 {
-  /* Do a placement new constructor for the promise type (we never call
-the new operator, just the constructor on the object in place in the
-frame).
+  /* Construct the promise object [dcl.fct.def.coroutine] / 5.7.
 
-First try to find a constructor with the same parameter list as the
-original function (if it has params), failing that find a constructor
-with no parameter list.  */
+First try to find a constructor with an argument list comprised of
+the parameter copies.  */
 
   if (DECL_ARGUMENTS (orig))
{
@@ -5129,20 +5125,27 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   else
r = NULL_TREE;
 
+  /* If that fails then the promise constructor argument list is empty.  */
   if (r == NULL_TREE || r == error_mark_node)
r = build_special_member_call (p, complete_ctor_identifier, NULL,
   promise_type, LOOKUP_NORMAL,
   tf_warning_or_error);
 
-  r = coro_build_cvt_void_expr_stmt (r, fn_start);
-  finish_expr_stmt (r);
+  /* If type_build_ctor_call() encounters deprecated implicit CTORs it will
+return true, and therefore we will execute this code path.  However,
+we might well not actually require a CTOR and under those conditions
+the build call above will not return a call expression, but the
+original instance object.  Do not attempt to add the statement unless
+it has side-effects.  */
+  if (r && r != error_mark_node && TREE_SIDE_EFFECTS (r))
+   finish_expr_stmt (r);
+}

[gcc r14-11737] c++/coro: ignore cleanup_point_exprs while expanding awaits [PR116793]

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:b4000f922425f7763bdab7bb8822975c0a669097

commit r14-11737-gb4000f922425f7763bdab7bb8822975c0a669097
Author: Arsen Arsenović 
Date:   Tue Sep 24 18:16:01 2024 +0200

c++/coro: ignore cleanup_point_exprs while expanding awaits [PR116793]

If we reach a CLEANUP_POINT_EXPR while trying to walk statements, we
actually care about the statement or statement list contained within it.

Indeed, such a construction started happening with
r15-3513-g964577c31df206, after temporary promotion.  In the test case
presented in PR116793, the compiler generated:

  T002_2_3];

  int T002 [value-expr: frame_ptr->T002_2_3];
<) >;
  struct _cleanup_task Aw0 [value-expr: frame_ptr->Aw0_2_3];
<) >;
<
Aw0

{_cleanup_task::await_ready (&Aw0), 
_cleanup_task::await_suspend<_task1::promise_type> (&Aw0, TARGET_EXPR ), <<< Unknown tree: aggr_init_expr
  4
  await_resume
  D.22443
  &Aw0 >>>}
0 >>>) >;
<;
  }
  D.22467 = 1;
  int & i [value-expr: frame_ptr->i_1_2];
  < (NON_LVALUE_EXPR )) >;>>;

... i.e. a statement list within a cleanup point.  In such a case, we
don't actually care about the cleanup point, but we do care about the
statement inside, so, we can just walk down into the CLEANUP_POINT_EXPR.

PR c++/116793

gcc/cp/ChangeLog:

* coroutines.cc (await_statement_expander): Just process
subtrees if encountering a CLEANUP_POINT_EXPR.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr116793-1.C: New test.

(cherry picked from commit d888a8a8dcf391197ae82e2bbf99507effc27950)

Diff:
---
 gcc/cp/coroutines.cc |  4 +++-
 gcc/testsuite/g++.dg/coroutines/pr116793-1.C | 26 ++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 3872e96b7429..5cacfb0db82d 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2045,7 +2045,9 @@ await_statement_expander (tree *stmt, int *do_subtree, 
void *d)
   tree res = NULL_TREE;
 
   /* Process a statement at a time.  */
-  if (STATEMENT_CLASS_P (*stmt) || TREE_CODE (*stmt) == BIND_EXPR)
+  if (STATEMENT_CLASS_P (*stmt)
+  || TREE_CODE (*stmt) == BIND_EXPR
+  || TREE_CODE (*stmt) == CLEANUP_POINT_EXPR)
 return NULL_TREE; /* Just process the sub-trees.  */
   else if (TREE_CODE (*stmt) == STATEMENT_LIST)
 {
diff --git a/gcc/testsuite/g++.dg/coroutines/pr116793-1.C 
b/gcc/testsuite/g++.dg/coroutines/pr116793-1.C
new file mode 100644
index ..ed2bdd26996a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr116793-1.C
@@ -0,0 +1,26 @@
+// https://gcc.gnu.org/PR116793
+#include 
+#include 
+struct _cleanup_task {
+  bool await_ready() const noexcept;
+  template 
+  bool await_suspend(std::coroutine_handle parent) noexcept;
+  std::tuple await_resume() noexcept;
+};
+struct _task1 {
+  struct promise_type final {
+std::suspend_always initial_suspend() noexcept;
+_task1 get_return_object() noexcept;
+void unhandled_exception() noexcept;
+struct awaiter final {
+  bool await_ready() noexcept;
+  void await_resume() noexcept;
+  void await_suspend(std::coroutine_handle h) noexcept;
+};
+awaiter final_suspend() noexcept;
+  };
+};
+_cleanup_task func(int &&);
+_task1 g() {
+  auto &&[i] = co_await func(3);
+}


[gcc r14-11738] c++, coroutines:Ensure bind exprs are visited once [PR98935].

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:bcd0d98c9f8f45c496bc2d0d0b6bda4fefcf9a6a

commit r14-11738-gbcd0d98c9f8f45c496bc2d0d0b6bda4fefcf9a6a
Author: Iain Sandoe 
Date:   Fri Nov 1 23:30:58 2024 +

c++, coroutines:Ensure bind exprs are visited once [PR98935].

Recent changes in the C++ FE and the coroutines implementation have
exposed a latent issue in which a bind expression containing a var
that we need to capture in the coroutine state gets visited twice.
This causes an ICE (from a checking assert).  Fixed by adding a pset
to the relevant tree walk.  Exit the callback early when the tree is
not a BIND_EXPR.

PR c++/98935

gcc/cp/ChangeLog:

* coroutines.cc (register_local_var_uses): Add a pset to the
tree walk to avoid visiting the same BIND_EXPR twice.  Make
an early exit for cases that the callback does not apply.
(cp_coroutine_transform::apply_transforms): Add a pset to the
tree walk for register_local_vars.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr98935.C: New test.

Signed-off-by: Iain Sandoe 
(cherry picked from commit bd8c7e71f516bae29a5a9e517b266141458f3977)

Diff:
---
 gcc/cp/coroutines.cc  | 158 +++---
 gcc/testsuite/g++.dg/coroutines/pr98935.C |  27 +
 2 files changed, 107 insertions(+), 78 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 5cacfb0db82d..77067be45ad4 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4135,6 +4135,9 @@ struct local_vars_frame_data
 static tree
 register_local_var_uses (tree *stmt, int *do_subtree, void *d)
 {
+  if (TREE_CODE (*stmt) != BIND_EXPR)
+return NULL_TREE;
+
   local_vars_frame_data *lvd = (local_vars_frame_data *) d;
 
   /* As we enter a bind expression - record the vars there and then recurse.
@@ -4142,88 +4145,86 @@ register_local_var_uses (tree *stmt, int *do_subtree, 
void *d)
  The bind index is a growing count of how many bind indices we've seen.
  We build a space in the frame for each local var.  */
 
-  if (TREE_CODE (*stmt) == BIND_EXPR)
+  tree lvar;
+  unsigned serial = 0;
+  for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL; lvar = DECL_CHAIN (lvar))
 {
-  tree lvar;
-  unsigned serial = 0;
-  for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
-  lvar = DECL_CHAIN (lvar))
-   {
- bool existed;
- local_var_info &local_var
-   = lvd->local_var_uses->get_or_insert (lvar, &existed);
- gcc_checking_assert (!existed);
- local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
- tree lvtype = TREE_TYPE (lvar);
- local_var.frame_type = lvtype;
- local_var.field_idx = local_var.field_id = NULL_TREE;
-
- /* Make sure that we only present vars to the tests below.  */
- if (TREE_CODE (lvar) != PARM_DECL
- && TREE_CODE (lvar) != VAR_DECL)
-   continue;
-
- /* We don't move static vars into the frame. */
- local_var.is_static = TREE_STATIC (lvar);
- if (local_var.is_static)
-   continue;
-
- poly_uint64 size;
- if (TREE_CODE (lvtype) == ARRAY_TYPE
- && !poly_int_tree_p (DECL_SIZE_UNIT (lvar), &size))
-   {
- sorry_at (local_var.def_loc, "variable length arrays are not"
-   " yet supported in coroutines");
- /* Ignore it, this is broken anyway.  */
- continue;
-   }
+  bool existed;
+  local_var_info &local_var
+   = lvd->local_var_uses->get_or_insert (lvar, &existed);
+  gcc_checking_assert (!existed);
+  local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
+  tree lvtype = TREE_TYPE (lvar);
+  local_var.frame_type = lvtype;
+  local_var.field_idx = local_var.field_id = NULL_TREE;
+
+  /* Make sure that we only present vars to the tests below.  */
+  if (TREE_CODE (lvar) != PARM_DECL
+ && TREE_CODE (lvar) != VAR_DECL)
+   continue;
 
- lvd->local_var_seen = true;
- /* If this var is a lambda capture proxy, we want to leave it alone,
-and later rewrite the DECL_VALUE_EXPR to indirect through the
-frame copy of the pointer to the lambda closure object.  */
- local_var.is_lambda_capture = is_capture_proxy (lvar);
- if (local_var.is_lambda_capture)
-   continue;
-
- /* If a variable has a value expression, then that's what needs
-to be processed.  */
- local_var.has_value_expr_p = DECL_HAS_VALUE_EXPR_P (lvar);
- if (local_var.has_value_expr_p)
-   continue;
-
- /* Make names depth+index unique, so that we can support nested
-scopes with identically named locals and still be able to
-identify them in the coroutine frame.  */
- tree lvname = DECL_NAME (lvar);
- char

[gcc r14-11740] c++/coroutines: Fix awaiter var creation [PR116506]

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:b69209936680dabbb7bbe08e71646a2c25ece0bf

commit r14-11740-gb69209936680dabbb7bbe08e71646a2c25ece0bf
Author: Iain Sandoe 
Date:   Thu Oct 31 08:40:08 2024 +

c++/coroutines: Fix awaiter var creation [PR116506]

Awaiters always need to have a coroutine state frame copy since
they persist across potential supensions.  It simplifies the later
analysis considerably to assign these early which we do when
building co_await expressions.

The cleanups in r15-3146-g47dbd69b1, unfortunately elided some of
processing used to cater for cases where the var created from an
xvalue, or is a pointer/reference type.

Corrected thus.

PR c++/116506
PR c++/116880

gcc/cp/ChangeLog:

* coroutines.cc (build_co_await): Ensure that xvalues are
materialised.  Handle references/pointer values in awaiter
access expressions.
(is_stable_lvalue): New.
* decl.cc (cxx_maybe_build_cleanup): Handle null arg.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr116506.C: New test.
* g++.dg/coroutines/pr116880.C: New test.

Signed-off-by: Iain Sandoe 
Co-authored-by: Jason Merrill 
(cherry picked from commit 4c743798b1d4530b327dad7c606c610f3811fdbf)

Diff:
---
 gcc/cp/coroutines.cc   | 106 +++--
 gcc/cp/decl.cc |   2 +-
 gcc/testsuite/g++.dg/coroutines/pr116506.C |  53 +++
 gcc/testsuite/g++.dg/coroutines/pr116880.C |  36 ++
 4 files changed, 144 insertions(+), 53 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 09e2f3410627..8811d249c025 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1066,6 +1066,28 @@ build_template_co_await_expr (location_t kw, tree type, 
tree expr, tree kind)
   return aw_expr;
 }
 
+/* Is EXPR an lvalue that will refer to the same object after a resume?
+
+   This is close to asking tree_invariant_p of its address, but that doesn't
+   distinguish temporaries from other variables.  */
+
+static bool
+is_stable_lvalue (tree expr)
+{
+  if (TREE_SIDE_EFFECTS (expr))
+return false;
+
+  for (; handled_component_p (expr);
+   expr = TREE_OPERAND (expr, 0))
+{
+  if (TREE_CODE (expr) == ARRAY_REF
+ && !TREE_CONSTANT (TREE_OPERAND (expr, 1)))
+   return false;
+}
+
+  return (TREE_CODE (expr) == PARM_DECL
+ || (VAR_P (expr) && !is_local_temp (expr)));
+}
 
 /*  This performs [expr.await] bullet 3.3 and validates the interface obtained.
 It is also used to build the initial and final suspend points.
@@ -1128,7 +1150,7 @@ build_co_await (location_t loc, tree a, 
suspend_point_kind suspend_kind,
   if (o_type && !VOID_TYPE_P (o_type))
 o_type = complete_type_or_else (o_type, o);
 
-  if (!o_type)
+  if (!o_type || o_type == error_mark_node)
 return error_mark_node;
 
   if (TREE_CODE (o_type) != RECORD_TYPE)
@@ -1155,56 +1177,35 @@ build_co_await (location_t loc, tree a, 
suspend_point_kind suspend_kind,
   if (!awrs_meth || awrs_meth == error_mark_node)
 return error_mark_node;
 
-  /* To complete the lookups, we need an instance of 'e' which is built from
- 'o' according to [expr.await] 3.4.
-
- If we need to materialize this as a temporary, then that will have to be
- 'promoted' to a coroutine frame var.  However, if the awaitable is a
- user variable, parameter or comes from a scope outside this function,
- then we must use it directly - or we will see unnecessary copies.
-
- If o is a variable, find the underlying var.  */
-  tree e_proxy = STRIP_NOPS (o);
-  if (INDIRECT_REF_P (e_proxy))
-e_proxy = TREE_OPERAND (e_proxy, 0);
-  while (TREE_CODE (e_proxy) == COMPONENT_REF)
+  /* [expr.await]/3.3 If o would be a prvalue, the temporary
+ materialization conversion ([conv.rval]) is applied.  */
+  if (!glvalue_p (o))
+o = get_target_expr (o, tf_warning_or_error);
+
+  /* [expr.await]/3.4 e is an lvalue referring to the result of evaluating the
+ (possibly-converted) o.
+
+ So, either reuse an existing stable lvalue such as a variable or
+ COMPONENT_REF thereof, or create a new a coroutine state frame variable
+ for the awaiter, since it must persist across suspension.  */
+  tree e_var = NULL_TREE;
+  tree e_proxy = o;
+  if (is_stable_lvalue (o))
+o = NULL_TREE; /* Use the existing entity.  */
+  else /* We need a non-temp var.  */
 {
-  e_proxy = TREE_OPERAND (e_proxy, 0);
-  if (INDIRECT_REF_P (e_proxy))
-   e_proxy = TREE_OPERAND (e_proxy, 0);
-  if (TREE_CODE (e_proxy) == CALL_EXPR)
+  tree p_type = TREE_TYPE (o);
+  tree o_a = o;
+  if (glvalue_p (o))
{
- /* We could have operator-> here too.  */
- tree op = TREE_OPERAND (CALL_EXPR_FN (e_proxy), 0);
- if (DECL_OVERLOADED_OPERATOR_P (op)
-  

[gcc r16-393] i386: Do not use explicit operands for MOVS instructions [PR120019]

2025-05-05 Thread Uros Bizjak via Gcc-cvs
https://gcc.gnu.org/g:c182f4d14d65b3e012ad65b5014d86352fabc86f

commit r16-393-gc182f4d14d65b3e012ad65b5014d86352fabc86f
Author: Uros Bizjak 
Date:   Mon May 5 13:59:43 2025 +0200

i386: Do not use explicit operands for MOVS instructions [PR120019]

Some assemblers do not support MOVS instructions with explicit operands.
Emit instruction with implicit operands, but prefix the instruction with a
segment override prefix if the memory operand refers to ADDR_SPACE_SEG_FS
or ADDR_SPACE_SEG_GS named address space.

PR target/120019

gcc/ChangeLog:

* config/i386/i386.cc (ix86_print_operand): Handle 'v' operand
modifier to emit segment override prefix.
* config/i386/i386.md (*strmovdi_rex_1): Use %v operand modifier
to emit segment override prefix.
(*strmovsi_1): Ditto.
(*strmovhi_1): Ditto.
(*strmovqi_1): Ditto.
(*rep_movdi_rex64): Ditto.
(*rep_movsi): Ditto.
(*rep_movqi): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr111657-1.c (dg-do): Change to "assemble".
(dg-options): Remove -masm=att and add -save-temps.
(dg-final): Update scan-assembler and scan-assembler-not strings.

Co-authored-by: Rainer Orth 

Diff:
---
 gcc/config/i386/i386.cc| 25 -
 gcc/config/i386/i386.md| 17 +
 gcc/testsuite/gcc.target/i386/pr111657-1.c |  8 
 3 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 5ad47e194348..df3e3efdfd02 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -13738,10 +13738,11 @@ print_reg (rtx x, int code, FILE *file)
H -- print a memory address offset by 8; used for sse high-parts
Y -- print condition for XOP pcom* instruction.
V -- print naked full integer register name without %.
+   v -- print segment override prefix
+ -- print a branch hint as 'cs' or 'ds' prefix
; -- print a semicolon (after prefixes due to bug in older gas).
~ -- print "i" if TARGET_AVX2, "f" otherwise.
-   ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
+   ^ -- print addr32 prefix if Pmode != word_mode
M -- print addr32 prefix for TARGET_X32 with VSIB address.
! -- print NOTRACK prefix for jxx/call/ret instructions if required.
N -- print maskz if it's constant 0 operand.
@@ -14243,6 +14244,28 @@ ix86_print_operand (FILE *file, rtx x, int code)
 
  return;
 
+   case 'v':
+ if (MEM_P (x))
+   {
+ switch (MEM_ADDR_SPACE (x))
+   {
+   case ADDR_SPACE_GENERIC:
+ break;
+   case ADDR_SPACE_SEG_FS:
+ fputs ("fs ", file);
+ break;
+   case ADDR_SPACE_SEG_GS:
+ fputs ("gs ", file);
+ break;
+   default:
+ gcc_unreachable ();
+   }
+   }
+ else
+   output_operand_lossage ("operand is not a memory reference, "
+   "invalid operand code 'v'");
+ return;
+
case '*':
  if (ASSEMBLER_DIALECT == ASM_ATT)
putc ('*', file);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index bb02ab0d4e1c..80b2023c088e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -58,10 +58,11 @@
 ;; H -- print a memory address offset by 8; used for sse high-parts
 ;; K -- print HLE lock prefix
 ;; Y -- print condition for XOP pcom* instruction.
+;; v -- print segment override prefix
 ;; + -- print a branch hint as 'cs' or 'ds' prefix
 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
-;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
+;; ^ -- print addr32 prefix if Pmode != word_mode
 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
 
 (define_c_enum "unspec" [
@@ -25643,7 +25644,7 @@
   operands[0] = SET_DEST (exp);
   operands[1] = SET_SRC (exp);
 
-  return "movsq\t{%1, %0|%0, %1}";
+  return "%^%v1movsq";
 }
   [(set_attr "type" "str")
(set_attr "memory" "both")
@@ -25666,7 +25667,7 @@
   operands[0] = SET_DEST (exp);
   operands[1] = SET_SRC (exp);
 
-  return "movs{l|d}\t{%1, %0|%0, %1}";
+  return "%^%v1movs{l|d}";
 }
   [(set_attr "type" "str")
(set_attr "memory" "both")
@@ -25689,7 +25690,7 @@
   operands[0] = SET_DEST (exp);
   operands[1] = SET_SRC (exp);
 
-  return "movsw\t{%1, %0|%0, %1}";
+  return "%^%v1movsw";
 }
   [(set_attr "type" "str")
(set_attr "memory" "both")
@@ -25712,7 +25713,7 @@
   operands[0] = SET_DEST (exp);
   operands[1] = SET_SRC (exp);
 
-  return "movsb\t{%1, %0|%0, %1}";
+  return "%^%v1movsb";
 }
   [(set_attr "type" "str")
(set_attr "me

[gcc r14-11725] c++, coroutines: Only allow void get_return_object if the ramp is void [PR100476].

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:98364636c194398d5dccb477e5405cb1d02a55f1

commit r14-11725-g98364636c194398d5dccb477e5405cb1d02a55f1
Author: Iain Sandoe 
Date:   Sat Aug 17 15:47:58 2024 +0100

c++, coroutines: Only allow void get_return_object if the ramp is void 
[PR100476].

Require that the value returned by get_return_object is convertible to
the ramp return.  This means that the only time we allow a void
get_return_object, is when the ramp is also a void function.

We diagnose this early to allow us to exit the ramp build if the return
values are incompatible.

PR c++/100476

gcc/cp/ChangeLog:

* coroutines.cc
(cp_coroutine_transform::build_ramp_function): Remove special
handling of void get_return_object expressions.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/coro-bad-gro-01-void-gro-non-class-coro.C:
Adjust expected diagnostic.
* g++.dg/coroutines/pr102489.C: Avoid void get_return_object.
* g++.dg/coroutines/pr103868.C: Likewise.
* g++.dg/coroutines/pr94879-folly-1.C: Likewise.
* g++.dg/coroutines/pr94883-folly-2.C: Likewise.
* g++.dg/coroutines/pr96749-2.C: Likewise.

Signed-off-by: Iain Sandoe 
(cherry picked from commit a0b431033c307982123abbff752045cfe7eda47f)

Diff:
---
 gcc/cp/coroutines.cc   | 49 ++
 .../coro-bad-gro-01-void-gro-non-class-coro.C  |  4 +-
 gcc/testsuite/g++.dg/coroutines/pr102489.C |  2 +-
 gcc/testsuite/g++.dg/coroutines/pr103868.C |  2 +-
 gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C  |  3 +-
 gcc/testsuite/g++.dg/coroutines/pr94883-folly-2.C  | 39 -
 gcc/testsuite/g++.dg/coroutines/pr96749-2.C|  2 +-
 7 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 3774e5595a0d..a6cbe07d1a28 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4646,8 +4646,9 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   /* Create the coro frame type, as far as it can be known at this stage.
  1. Types we already know.  */
 
-  tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
   tree promise_type = get_coroutine_promise_type (orig);
+  tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
+  bool void_ramp_p = VOID_TYPE_P (fn_return_type);
 
   /* 2. Types we need to define or look up.  */
 
@@ -4951,7 +4952,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, nullptr_node);
   cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond);
   finish_if_stmt_cond (cond, if_stmt);
-  if (VOID_TYPE_P (fn_return_type))
+  if (void_ramp_p)
{
  /* Execute the get-return-object-on-alloc-fail call...  */
  finish_expr_stmt (grooaf);
@@ -5157,7 +5158,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
 coro_get_return_object_identifier,
 fn_start, NULL, /*musthave=*/true);
   /* Without a return object we haven't got much clue what's going on.  */
-  if (get_ro == error_mark_node)
+  if (!get_ro || get_ro == error_mark_node)
 {
   BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
   DECL_SAVED_TREE (orig) = newbody;
@@ -5165,10 +5166,20 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   suppress_warning (orig, OPT_Wreturn_type);
   return false;
 }
+ 
+  /* Check for a bad get return object type.
+ [dcl.fct.def.coroutine] / 7 requires:
+ The expression promise.get_return_object() is used to initialize the
+ returned reference or prvalue result object ... */
+  tree gro_type = TREE_TYPE (get_ro);
+  if (VOID_TYPE_P (gro_type) && !void_ramp_p)
+{
+  error_at (fn_start, "no viable conversion from % provided by"
+   " % to return type %qT", fn_return_type);
+  return false;
+}
 
   tree gro_context_body = push_stmt_list ();
-  tree gro_type = TREE_TYPE (get_ro);
-  bool gro_is_void_p = VOID_TYPE_P (gro_type);
 
   tree gro = NULL_TREE;
   tree gro_bind_vars = NULL_TREE;
@@ -5177,8 +5188,11 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   tree gro_cleanup_stmt = NULL_TREE;
   /* We have to sequence the call to get_return_object before initial
  suspend.  */
-  if (gro_is_void_p)
-r = get_ro;
+  if (void_ramp_p)
+{
+  gcc_checking_assert (VOID_TYPE_P (gro_type));
+  r = get_ro;
+}
   else if (same_type_p (gro_type, fn_return_type))
 {
  /* [dcl.fct.def.coroutine] / 7
@@ -5264,28 +5278,11 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
  for an object of the return type.  */
 
   if (same_type_p (gro_type, fn_return_type))
-r = gro_is_void_p ? NULL_TREE : DECL_RESULT (orig);
-  e

[gcc r14-11731] c++: don't remove labels during coro-early-expand-ifns [PR105104]

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:5a275b5bebdf7746af590fa57378cd48cb8e679a

commit r14-11731-g5a275b5bebdf7746af590fa57378cd48cb8e679a
Author: Arsen Arsenović 
Date:   Fri Aug 16 19:07:01 2024 +0200

c++: don't remove labels during coro-early-expand-ifns [PR105104]

In some scenarios, it is possible for the CFG cleanup to cause one of
the labels mentioned in CO_YIELD, which coro-early-expand-ifns intends
to remove, to become part of some statement.  As a result, when that
label is removed, the statement it became part of becomes invalid,
crashing the compiler.

There doesn't appear to be a reason to remove the labels (anymore, at
least), so let's not do that.

PR c++/105104

gcc/ChangeLog:

* coroutine-passes.cc (execute_early_expand_coro_ifns): Don't
remove any labels.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/torture/pr105104.C: New test.

(cherry picked from commit d9c54e9a036189e8961ec17e118fccf794d7bfab)

Diff:
---
 gcc/coroutine-passes.cc| 26 --
 gcc/testsuite/g++.dg/coroutines/torture/pr105104.C | 40 ++
 2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/gcc/coroutine-passes.cc b/gcc/coroutine-passes.cc
index c0d6eca7c070..b962d7598c43 100644
--- a/gcc/coroutine-passes.cc
+++ b/gcc/coroutine-passes.cc
@@ -293,9 +293,6 @@ execute_early_expand_coro_ifns (void)
   /* Some of the possible YIELD points will hopefully have been removed by
  earlier optimisations; record the ones that are still present.  */
   hash_map, tree> destinations;
-  /* Labels we added to carry the CFG changes, we need to remove these to
- avoid confusing EH.  */
-  hash_set to_remove;
   /* List of dispatch points to update.  */
   auto_vec actor_worklist;
   basic_block bb;
@@ -374,8 +371,6 @@ execute_early_expand_coro_ifns (void)
}
  else
dst_dest = dst_tgt;
- to_remove.add (res_tgt);
- to_remove.add (dst_tgt);
  /* lose the co_yield.  */
  gsi_remove (&gsi, true);
  stmt = gsi_stmt (gsi); /* next. */
@@ -463,27 +458,6 @@ execute_early_expand_coro_ifns (void)
}
 }
 
-  /* Remove the labels we inserted to map our hidden CFG, this
- avoids confusing block merges when there are also EH labels.  */
-  FOR_EACH_BB_FN (bb, cfun)
-for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
-  {
-   gimple *stmt = gsi_stmt (gsi);
-   if (glabel *glab = dyn_cast (stmt))
- {
-   tree rem = gimple_label_label (glab);
-   if (to_remove.contains (rem))
- {
-   gsi_remove (&gsi, true);
-   to_remove.remove (rem);
-   continue; /* We already moved to the next insn.  */
- }
- }
-   else
- break;
-   gsi_next (&gsi);
-  }
-
   /* Changed the CFG.  */
   todoflags |= TODO_cleanup_cfg;
   return todoflags;
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr105104.C 
b/gcc/testsuite/g++.dg/coroutines/torture/pr105104.C
new file mode 100644
index ..fcc783e3066d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr105104.C
@@ -0,0 +1,40 @@
+// https://gcc.gnu.org/PR105104
+// { dg-additional-options "-O" }
+
+#include 
+
+// ICE during GIMPLE pass: coro-early-expand-ifs. final_awaiter::await_resume 
is
+// non-void, and optimizations are enabled.
+
+struct return_object
+{
+  struct promise_type
+  {
+static constexpr std::suspend_always initial_suspend () noexcept
+{
+  return {};
+}
+
+struct final_awaiter
+{
+  static constexpr bool await_ready () noexcept { return false; }
+  static constexpr void await_suspend (std::coroutine_handle<>) noexcept {}
+  static constexpr int await_resume () noexcept { return {}; }
+};
+static constexpr final_awaiter final_suspend () noexcept { return {}; }
+
+static void unhandled_exception () { throw; }
+
+return_object get_return_object () { return {}; }
+
+static constexpr void return_void () noexcept {}
+  };
+};
+
+return_object
+coroutine ()
+{
+  co_return;
+}
+
+return_object f = coroutine ();


[gcc r14-11732] coros: mark .CO_YIELD as LEAF [PR106973]

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:74cfbedd24cfc4bb26b33bdb0b7c55a9139cd757

commit r14-11732-g74cfbedd24cfc4bb26b33bdb0b7c55a9139cd757
Author: Arsen Arsenović 
Date:   Tue Sep 3 17:14:13 2024 +0200

coros: mark .CO_YIELD as LEAF [PR106973]

We rely on .CO_YIELD calls being followed by an assignment (optionally)
and then a switch/if in the same basic block.  This implies that a
.CO_YIELD can never end a block.  However, since a call to .CO_YIELD is
still a call, if the function containing it calls setjmp, GCC thinks
that the .CO_YIELD can introduce abnormal control flow, and generates an
edge for the call.

We know this is not the case; .CO_YIELD calls get removed quite early on
and have no effect, and result in no other calls, so .CO_YIELD can be
considered a leaf function, preventing generating an edge when calling
it.

PR c++/106973 - coroutine generator and setjmp

PR c++/106973

gcc/ChangeLog:

* internal-fn.def (CO_YIELD): Mark as ECF_LEAF.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr106973.C: New test.

(cherry picked from commit 7b7ad3f4b2455072f42e7884b93fd96ebb920bc8)

Diff:
---
 gcc/internal-fn.def|  2 +-
 gcc/testsuite/g++.dg/coroutines/pr106973.C | 22 ++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 848bb9dbff3f..02e5d17d5dd4 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -559,7 +559,7 @@ DEF_INTERNAL_FN (DIVMOD, ECF_CONST | ECF_LEAF, NULL)
 
 /* For coroutines.  */
 DEF_INTERNAL_FN (CO_ACTOR, ECF_NOTHROW | ECF_LEAF, NULL)
-DEF_INTERNAL_FN (CO_YIELD, ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (CO_YIELD, ECF_NOTHROW | ECF_LEAF, NULL)
 DEF_INTERNAL_FN (CO_SUSPN, ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (CO_FRAME, ECF_PURE | ECF_NOTHROW | ECF_LEAF, NULL)
 
diff --git a/gcc/testsuite/g++.dg/coroutines/pr106973.C 
b/gcc/testsuite/g++.dg/coroutines/pr106973.C
new file mode 100644
index ..6db6cbc7711a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr106973.C
@@ -0,0 +1,22 @@
+// https://gcc.gnu.org/PR106973
+// { dg-require-effective-target indirect_jumps }
+#include 
+#include 
+
+struct generator;
+struct generator_promise {
+  generator get_return_object();
+  std::suspend_always initial_suspend();
+  std::suspend_always final_suspend() noexcept;
+  std::suspend_always yield_value(int);
+  void unhandled_exception();
+};
+
+struct generator {
+  using promise_type = generator_promise;
+};
+jmp_buf foo_env;
+generator foo() {
+  setjmp(foo_env);
+  co_yield 1;
+}


[gcc r16-390] RISC-V: Fix gcc.target/riscv/predef-19.c [PR120054]

2025-05-05 Thread Kito Cheng via Gcc-cvs
https://gcc.gnu.org/g:fcc74146e3e0bfd30f9ccc12359991d73fe928f9

commit r16-390-gfcc74146e3e0bfd30f9ccc12359991d73fe928f9
Author: Kito Cheng 
Date:   Mon May 5 10:08:22 2025 +0800

RISC-V: Fix gcc.target/riscv/predef-19.c [PR120054]

gcc/testsuite/ChangeLog:

PR target/120054
* gcc.target/riscv/predef-19.c: Adjust testcase.

Diff:
---
 gcc/testsuite/gcc.target/riscv/predef-19.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/predef-19.c 
b/gcc/testsuite/gcc.target/riscv/predef-19.c
index ca3d57abca90..f2b4d9b30486 100644
--- a/gcc/testsuite/gcc.target/riscv/predef-19.c
+++ b/gcc/testsuite/gcc.target/riscv/predef-19.c
@@ -27,10 +27,6 @@ int main () {
 #error "__riscv_zicsr"
 #endif
 
-#if !defined(_riscv_zmmul)
-#error "__riscv_zmmul"
-#endif
-
 #if !defined(__riscv_zve32x)
 #error "__riscv_zve32x"
 #endif


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression pr77973

2025-05-05 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:5fcd9bb0d57e56f70c3291b59b54368372c9c69f

commit 5fcd9bb0d57e56f70c3291b59b54368372c9c69f
Author: Mikael Morin 
Date:   Mon May 5 13:48:49 2025 +0200

Correction régression pr77973

Diff:
---
 gcc/fortran/trans-openmp.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 01d9263fb838..7e8b51fbf5a6 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -242,7 +242,8 @@ gfc_omp_privatize_by_reference (const_tree decl)
  || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
  || GFC_DECL_CRAY_POINTEE (decl)
  || GFC_DECL_ASSOCIATE_VAR_P (decl)
- || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl
+ || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
+ || !TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
return false;
 
   if (!DECL_ARTIFICIAL (decl)


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression guality/arg1

2025-05-05 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:708eb59b45197553bcfcd8b178fda6716421614e

commit 708eb59b45197553bcfcd8b178fda6716421614e
Author: Mikael Morin 
Date:   Mon May 5 17:03:44 2025 +0200

Correction régression guality/arg1

Diff:
---
 gcc/fortran/trans-decl.cc  |  9 +++--
 gcc/fortran/trans-types.cc | 17 -
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 99c53fab755a..92a0ccdb3588 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -1264,10 +1264,15 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
 {
   tree size, range;
 
+  tree lower = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
+  if (lower == NULL_TREE)
+   lower = gfc_index_zero_node;
+
   size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  GFC_TYPE_ARRAY_SIZE (type), gfc_index_one_node);
-  range = build_range_type (gfc_array_index_type, gfc_index_zero_node,
-   size);
+  size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+ size, lower);
+  range = build_range_type (gfc_array_index_type, lower, size);
   TYPE_DOMAIN (type) = range;
   layout_type (type);
 }
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index dd8c306b3b32..9568d8f821ab 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -1860,6 +1860,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * 
as, gfc_packed packed,
   mpz_t stride;
   mpz_t spc;
   mpz_t delta;
+  mpz_t *lbound0 = nullptr;
   gfc_expr *expr;
 
   mpz_init_set_ui (offset, 0);
@@ -1889,6 +1890,8 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * 
as, gfc_packed packed,
   expr = as->lower[n];
   if (expr && expr->expr_type == EXPR_CONSTANT)
 {
+ if (n == 0)
+   lbound0 = &expr->value.integer;
   tmp = gfc_conv_mpz_to_tree (expr->value.integer,
  gfc_index_integer_kind);
 }
@@ -2004,13 +2007,25 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * 
as, gfc_packed packed,
  mpz_t size;
  mpz_init (size);
  mpz_sub_ui (size, stride, 1);
+ if (as->rank == 1 && lbound0)
+   mpz_add (size, size, *lbound0);
+ else if (as->rank == 1 && as->lower[0] == nullptr)
+   mpz_add_ui (size, size, 1);
  max_idx = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
}
   else
max_idx = NULL_TREE;
 
+  tree lower;
+  if (as->rank == 1 && lbound0)
+   lower = gfc_conv_mpz_to_tree (*lbound0, gfc_index_integer_kind);
+  else if (as->rank == 1 && as && as->lower[0] == nullptr)
+   lower = gfc_index_one_node;
+  else
+   lower = gfc_index_zero_node;
+
   TYPE_DOMAIN (type) = build_range_type (gfc_array_index_type,
-gfc_index_zero_node, max_idx);
+lower, max_idx);
   TREE_TYPE (type) = etype;
 }


[gcc r16-392] PR modula2/120117: ICE when attempting to obtain the MAX of an aliased set type

2025-05-05 Thread Gaius Mulley via Gcc-cvs
https://gcc.gnu.org/g:bb83283e5c5c55eab7493a58c5e415aa56f5940c

commit r16-392-gbb83283e5c5c55eab7493a58c5e415aa56f5940c
Author: Gaius Mulley 
Date:   Mon May 5 18:16:20 2025 +0100

PR modula2/120117: ICE when attempting to obtain the MAX of an aliased set 
type

The ICE occurred because of a bug in M2GenGCC.mod:FoldBecomes which
attempted to remove the same quadruple twice.  Thereafter cc1gm2
generated an erroneous error type error as PCSymBuild did not skip
an aliased set type.  The type of the const was set incorrectly
(as a set type) rather than the type of the set element.

gcc/m2/ChangeLog:

PR modula2/120117
* gm2-compiler/M2GenGCC.mod (FoldBecomes): Remove the call to
RemoveQuad since this is performed by TypeCheckBecomes.
* gm2-compiler/PCSymBuild.mod (buildConstFunction): Rewrite
header comment.
Check for a set or a type aliased set and appropriately
skip type equivalences and obtain the element type.
* gm2-compiler/SymbolTable.mod (PutConst): Add call to
CheckBreak.

gcc/testsuite/ChangeLog:

PR modula2/120117
* gm2/pim/pass/highbit.mod: New test.
* gm2/pim/pass/highbit2.mod: New test.

Signed-off-by: Gaius Mulley 

Diff:
---
 gcc/m2/gm2-compiler/M2GenGCC.mod|  3 ---
 gcc/m2/gm2-compiler/PCSymBuild.mod  | 13 +++--
 gcc/m2/gm2-compiler/SymbolTable.mod |  1 +
 gcc/testsuite/gm2/pim/pass/highbit.mod  | 13 +
 gcc/testsuite/gm2/pim/pass/highbit2.mod | 13 +
 5 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod
index a1e3c07809aa..bc1d588fce6e 100644
--- a/gcc/m2/gm2-compiler/M2GenGCC.mod
+++ b/gcc/m2/gm2-compiler/M2GenGCC.mod
@@ -2914,9 +2914,6 @@ BEGIN
  IF TypeCheckBecomes (p, quad)
  THEN
 PerformFoldBecomes (p, quad)
- ELSE
-GetQuad (quad, op, des, op2, expr) ;
-RemoveQuad (p, des, quad)
  END
   END
END
diff --git a/gcc/m2/gm2-compiler/PCSymBuild.mod 
b/gcc/m2/gm2-compiler/PCSymBuild.mod
index b124c3ea6729..3bffe8674a4f 100644
--- a/gcc/m2/gm2-compiler/PCSymBuild.mod
+++ b/gcc/m2/gm2-compiler/PCSymBuild.mod
@@ -64,7 +64,7 @@ FROM SymbolTable IMPORT NulSym, ModeOfAddr, ProcedureKind,
 GetFromOuterModule,
 CheckForEnumerationInCurrentModule,
 GetMode, PutVariableAtAddress, ModeOfAddr, SkipType,
-IsSet, PutConstSet,
+IsSet, PutConstSet, IsType,
 IsConst, IsConstructor, PutConst, PutConstructor,
 PopValue, PushValue,
 MakeTemporary, PutVar,
@@ -1408,9 +1408,10 @@ END TypeToMeta ;
 
 
 (*
-   buildConstFunction - we are only concerned about resolving the return type o
+   buildConstFunction - we are only concerned about resolving the return type 
of
 a function, so we can ignore all parameters - except
-the first one in the case of VAL(type, foo).
+the first one in the case of VAL(type, foo)
+and the type of bar in MIN (bar) and MAX (bar).
 buildConstFunction uses a unary exprNode to represent
 a function.
 *)
@@ -1866,11 +1867,11 @@ BEGIN
 THEN
IF (func=Min) OR (func=Max)
THEN
-  IF IsSet (sym)
+  IF IsSet (sym) OR (IsType (sym) AND IsSet (SkipType (sym)))
   THEN
- type := SkipType(GetType(sym))
+ type := GetType (SkipType (sym))
   ELSE
- (* sym is the type required for MAX, MIN and VAL *)
+ (* sym is the type required for MAX, MIN and VAL.  *)
  type := sym
   END
ELSE
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod 
b/gcc/m2/gm2-compiler/SymbolTable.mod
index 551bbecc7886..ff661dcf4e7e 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -7265,6 +7265,7 @@ VAR
pSym: PtrToSymbol ;
 BEGIN
pSym := GetPsym(Sym) ;
+   CheckBreak (Sym) ;
WITH pSym^ DO
   CASE SymbolType OF
 
diff --git a/gcc/testsuite/gm2/pim/pass/highbit.mod 
b/gcc/testsuite/gm2/pim/pass/highbit.mod
new file mode 100644
index ..c9c872a62f31
--- /dev/null
+++ b/gcc/testsuite/gm2/pim/pass/highbit.mod
@@ -0,0 +1,13 @@
+MODULE highbit ;
+
+FROM libc IMPORT printf ;
+
+TYPE
+   set = BITSET ;
+
+CONST
+   HighBit = MAX (set) ;
+
+BEGIN
+   printf ("the MAX (set) = %d\n", HighBit)
+END highbit.
diff --git a/gcc/testsuite/gm2/pim/pass/highbit2.mod 
b/gcc/testsuite/gm2/pim/pass/highbit2.mod
new file mode 10064

[gcc/ibm/heads/gcc-14-branch] (1123 commits) ibm: Merge up to top of releases/gcc-14

2025-05-05 Thread Surya Kumari Jangala via Gcc-cvs
The branch 'ibm/heads/gcc-14-branch' was updated to point to:

 e8224a16f678... ibm: Merge up to top of releases/gcc-14

It previously pointed to:

 7ea4c6f44d3f... ibm: Merge up to top of releases/gcc-14

Diff:

Summary of changes (added commits):
---

  e8224a1... ibm: Merge up to top of releases/gcc-14
  c120e04... Daily bump. (*)
  475cec3... Fortran: pure subroutine with pure procedure as dummy [PR10 (*)
  30432ff... c++: UNBOUND_CLASS_TEMPLATE context substitution [PR119981] (*)
  fd9d35f... testsuite: Force -mcmodel=small for gcc.target/aarch64/pr11 (*)
  51d7659... Fix GNAT build failure for x86/FreeBSD (*)
  1ca1c1f... AVR: target/119989 - Add missing clobbers to xload__l (*)
  3418d74... libstdc++: [_GLIBCXX_INLINE_VERSION] Fix tests failures (*)
  e363940... RISC-V: vsetvl: elide abnormal edges from LCM computations  (*)
  ae6ce4c... RISC-V: Do not lift up vsetvl into non-transparent blocks [ (*)
  eaa9b75... Daily bump. (*)
  96729ba... Remove other processors from X86_TUNE_DEST_FALSE_DEP_FOR_GL (*)
  d23d35d... libstdc++: Improve optional's <=> constraint recursion work (*)
  d03c585... libstdc++: Add code comment documenting LWG 4027 change [PR (*)
  d4f5243... libstdc++: Implement LWG 4027 change to possibly-const-rang (*)
  d3cb17b... c++: prev declared hidden tmpl friend inst, cont [PR119807] (*)
  615e392... Daily bump. (*)
  1e91580... c++: format attribute redeclaration [PR116954] (*)
  8dce1aa... c++: shortcut constexpr vector ctor [PR113835] (*)
  8f4df0d... middle-end: fix masking for partial vectors and early break (*)
  9ce3811... aarch64: force operand to fresh register to avoid subreg is (*)
  3e44824... Daily bump. (*)
  035da7b... Daily bump. (*)
  294ed13... Daily bump. (*)
  57f930f... libbacktrace: Add hpux fileline support (*)
  2a9fd7e... Daily bump. (*)
  cd7c5d9... sra: Clear grp_same_access_path of acesses created by total (*)
  19dd791... sra: Avoid creating TBAA hazards (PR118924) (*)
  29004ac... s390: Accept only Pmode for registers AP/FP/RA [PR119235] (*)
  8d70737... c++: templates, attributes, #pragma target [PR114772] (*)
  8a88414... libcpp: Fix incorrect line numbers in large files [PR108900 (*)
  70eaec5... c++: constexpr, trivial, and non-alias target [PR111075] (*)
  9ef0cf0... Daily bump. (*)
  d7b5fe3... [14] Use --param=aarch64-autovec-preference=2 instead of =s (*)
  4108c75... tree-optimization/119778 - properly mark abnormal edge sour (*)
  2bb4a43... aarch64: Add test case. (*)
  c8fe937... middle-end/119706 - allow POLY_INT_CST as is_gimple_mem_ref (*)
  a27f6a4... target/119549 - fixup handling of -mno-sse4 in target attri (*)
  97dde42... tree-optimization/119534 - reject bogus emulated vectorized (*)
  721c612... Daily bump. (*)
  9051989... Daily bump. (*)
  d338d6c... Daily bump. (*)
  88b3c89... d: Fix ICE: type variant differs by TYPE_MAX_VALUE with -g  (*)
  d1b7ee4... d: Fix ICE in dwarf2out_imported_module_or_decl, at dwarf2o (*)
  aec3b99... d: Fix forward referenced enums missing type names in debug (*)
  d490c58... libatomic: Fix up libat_{,un}lock_n for mingw [PR119796] (*)
  50bd360... libatomic: Fix up libat_{,un}lock_n [PR119796] (*)
  40c5065... bitintlower: Fix interaction of gimple_assign_copy_p stmts  (*)
  efb2261... expmed: Always use QImode for init_expmed set_zero_cost [PR (*)
  438c4df... driver: On linux hosts disable ASLR during -freport-bug [PR (*)
  2aa8123... driver: Fix up -freport-bug for ASLR [PR119727] (*)
  056a01f... bitintlower: Fix up handling of SSA_NAME copies in coalesci (*)
  008ba21... bitintlower: Fix up handling of nested casts in m_upward_2l (*)
  8581982... libquadmath: Fix up THREEp96 constant in expq (*)
  293a95b... lto: lto-opts fixes [PR119625] (*)
  c0946fe... c: Fix ICEs with -fsanitize=pointer-{subtract,compare} [PR1 (*)
  7381ea8... combine: Use reg_used_between_p rather than modified_betwee (*)
  2048dcc... LoongArch: Change {dg-do-what-default} save and restore log (*)
  022ef0b... Daily bump. (*)
  459b93d... Daily bump. (*)
  a295863... libstdc++: Correct preprocessing checks for floatX_t and bf (*)
  203bce1... i386: Enable -mnop-mcount for -fpic with PLTs [PR119386] (*)
  1500a9c... i386: Prefer PLT indirection for __fentry__ calls under -fP (*)
  efe332f... Daily bump. (*)
  62151c3... Fix wrong optimization of conditional expression with enume (*)
  c344377... aarch64: Disable sysreg feature gating (*)
  8cc672d... x86: Update gcc.target/i386/apx-interrupt-1.c (*)
  a33e280... APX: Don't use red-zone with 32 GPRs and no caller-saved re (*)
  d275b37... Extend check-function-bodies to allow label and directives (*)
  b61acf5... RISC-V: Put jump table in text for large code model (*)
  52c1f60... RISC-V: Fix vec_duplicate[bimode] expander [PR119572]. (*)
  94ef806... aarch64: Split aarch64_combinev16qi before RA [PR115258] (*)
  a38e9e0... aarch64: Avoid unnecessary use of 2-input TBLs [PR115258] (*)
  2a4b0a1... vect: Enforce dr_with_seg_len::align precon

[gcc(refs/vendors/ibm/heads/gcc-14-branch)] ibm: Merge up to top of releases/gcc-14

2025-05-05 Thread Surya Kumari Jangala via Gcc-cvs
https://gcc.gnu.org/g:e8224a16f6789610b8775aed520a24bbb2c01ab0

commit e8224a16f6789610b8775aed520a24bbb2c01ab0
Merge: 7ea4c6f44d3f c120e047ecb5
Author: Surya Kumari Jangala 
Date:   Fri May 2 03:20:33 2025 -0500

ibm: Merge up to top of releases/gcc-14

2025-05-02  Surya Kumari Jangala  

Merge up to releases/gcc-14 c120e047ecb5f488efffdccbdcacc1ce18e29f3a

Diff:

 gcc/ChangeLog  |  3514 +
 gcc/ChangeLog.ibm  | 4 +
 gcc/DATESTAMP  | 2 +-
 gcc/Makefile.in| 1 +
 gcc/ada/ChangeLog  |   156 +
 gcc/ada/Makefile.rtl   | 1 +
 gcc/ada/checks.adb |10 +-
 gcc/ada/exp_aggr.adb   |54 +-
 gcc/ada/exp_aggr.ads   | 4 +
 gcc/ada/exp_ch3.adb|15 +-
 gcc/ada/exp_ch7.adb| 6 +
 gcc/ada/exp_put_image.adb  | 3 +-
 gcc/ada/exp_util.adb   | 1 +
 gcc/ada/freeze.adb |26 +-
 gcc/ada/gcc-interface/decl.cc  | 8 +
 gcc/ada/gcc-interface/trans.cc |16 +-
 gcc/ada/gen_il-gen-gen_nodes.adb   | 2 +-
 gcc/ada/gnatvsn.ads| 3 +-
 gcc/ada/libgnarl/s-taprop__dummy.adb   |11 +-
 gcc/ada/libgnat/a-ngcoar.adb   |42 +-
 gcc/ada/libgnat/a-ngrear.adb   |   109 +-
 gcc/ada/libgnat/s-dorepr__freebsd.adb  |   172 +
 gcc/ada/par-ch6.adb| 1 +
 gcc/ada/sem_ch12.adb   |37 +-
 gcc/ada/sem_res.adb| 2 +-
 gcc/ada/sem_warn.adb   | 4 +
 gcc/ada/version.c  | 5 +-
 gcc/analyzer/ChangeLog |43 +
 gcc/analyzer/analyzer.cc   |15 +-
 gcc/analyzer/analyzer.h| 4 +-
 gcc/analyzer/engine.cc | 2 +-
 gcc/analyzer/kf.cc |26 +
 gcc/analyzer/known-function-manager.cc |38 +-
 gcc/analyzer/known-function-manager.h  | 5 +
 gcc/analyzer/sm-file.cc| 8 +
 gcc/analyzer/sm-malloc.cc  | 1 +
 gcc/analyzer/sm-signal.cc  |11 +-
 gcc/asan.cc|51 +-
 gcc/auto-profile.cc| 4 +-
 gcc/builtins.cc|73 +-
 gcc/c-family/ChangeLog |70 +
 gcc/c-family/c-ada-spec.cc | 4 +-
 gcc/c-family/c-common.cc   |11 +-
 gcc/c-family/c-cppbuiltin.cc   |19 +-
 gcc/c-family/c-pretty-print.cc | 6 +-
 gcc/c-family/c-warn.cc |20 +-
 gcc/c/ChangeLog|   108 +
 gcc/c/c-decl.cc|   123 +-
 gcc/c/c-objc-common.h  | 2 +
 gcc/c/c-parser.cc  |36 +-
 gcc/c/c-tree.h |21 +-
 gcc/c/c-typeck.cc  |   388 +-
 gcc/cfgexpand.cc   | 7 +-
 gcc/cgraph.cc  |14 +-
 gcc/combine.cc |38 +-
 gcc/common/config/i386/cpuinfo.h   | 1 +
 gcc/common/config/i386/i386-common.cc  |63 +-
 gcc/common/config/i386/i386-isas.h | 2 +-
 gcc/config.in  | 7 +
 gcc/config/aarch64/aarch64-builtins.cc |   190 +-
 gcc/config/aarch64/aarch64-cores.def   | 9 +-
 gcc/config/aarch64/aarch64-early-ra.cc |57 +-
 gcc/config/aarch64/aarch64-freebsd.h   | 1 +
 gcc/config/aarch64/aarch64-ldp-fusion.cc   |   158 +-
 gcc/config/aarch64/aarch64-protos.h| 2 +
 gcc/config/aarch64/aarch64-simd.md | 2 +-
 gcc/config/aarch64/aarch64-sve-builtins-base.cc|17 +-
 gcc/config/aarch64/aarch64-sve-builtins-base.def   |13 +-
 gcc/config/aarch64/aarch64-sve-builtins-sve2.cc| 8 +-
 gcc/config/aarch64/aarch64-sve-builtins-sve2.def   | 4 +-
 gcc/config/aarch64/aarch64-sve-builtins-sve2.h | 4 +-
 gcc/config/aarch64/aarch64-sve-builtins.cc |   107 +-
 gcc/config/aarch64/aarch64-sve2.md | 8 +-
 gcc/config/aarch64/aarch64-tune.md 

[gcc r14-11726] c++, coroutines: Allow convertible get_return_on_allocation_fail [PR109682].

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:1b3addb6fe05a80d5e043fbb12cc9c0cc426b0e6

commit r14-11726-g1b3addb6fe05a80d5e043fbb12cc9c0cc426b0e6
Author: Iain Sandoe 
Date:   Sat Aug 17 16:55:29 2024 +0100

c++, coroutines: Allow convertible get_return_on_allocation_fail [PR109682].

We have been requiring the get_return_on_allocation_fail() call to have the
same type as the ramp.  This is not intended by the standard, so relax that
to allow anything convertible to the ramp return.

PR c++/109682

gcc/cp/ChangeLog:

* coroutines.cc
(cp_coroutine_transform::build_ramp_function): Allow for cases where
get_return_on_allocation_fail has a type convertible to the ramp
return type.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr109682.C: New test.

Signed-off-by: Iain Sandoe 
(cherry picked from commit f4915e6c4cd42e7d6f397dc36fab507cc47dad05)

Diff:
---
 gcc/cp/coroutines.cc   | 19 ++-
 gcc/testsuite/g++.dg/coroutines/pr109682.C | 28 
 2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index a6cbe07d1a28..00a016d1bd31 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4946,25 +4946,18 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
 control to the caller of the coroutine and the return value is
 obtained by a call to T::get_return_object_on_allocation_failure(),
 where T is the promise type.  */
-
-  gcc_checking_assert (same_type_p (fn_return_type, TREE_TYPE (grooaf)));
   tree if_stmt = begin_if_stmt ();
   tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, nullptr_node);
   cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond);
   finish_if_stmt_cond (cond, if_stmt);
+  r = NULL_TREE;
   if (void_ramp_p)
-   {
- /* Execute the get-return-object-on-alloc-fail call...  */
- finish_expr_stmt (grooaf);
- /* ... but discard the result, since we return void.  */
- finish_return_stmt (NULL_TREE);
-   }
+   /* Execute the get-return-object-on-alloc-fail call...  */
+   finish_expr_stmt (grooaf);
   else
-   {
- /* Get the fallback return object.  */
- r = build_cplus_new (fn_return_type, grooaf, tf_warning_or_error);
- finish_return_stmt (r);
-   }
+   /* Get the fallback return object.  */
+   r = grooaf;
+  finish_return_stmt (r);
   finish_then_clause (if_stmt);
   finish_if_stmt (if_stmt);
 }
diff --git a/gcc/testsuite/g++.dg/coroutines/pr109682.C 
b/gcc/testsuite/g++.dg/coroutines/pr109682.C
new file mode 100644
index ..24aab921ab22
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr109682.C
@@ -0,0 +1,28 @@
+
+#include 
+#include 
+
+struct test
+{
+  test () {}
+  test (int) {}
+
+  struct promise_type {
+test get_return_object () { return {}; }
+// vvv
+static int get_return_object_on_allocation_failure () { return {}; }
+std::suspend_never initial_suspend () noexcept { return {}; }
+std::suspend_never final_suspend () noexcept { return {}; }
+void return_void () {}
+void unhandled_exception () {}
+  };
+};
+
+test
+f () { co_return; }
+
+int
+main ()
+{
+  f ();
+}


[gcc r14-11727] c++, coroutines: Rework handling of throwing_cleanups [PR102051].

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:ce3f523f9cb4c20704bc5f41b8fbc34b5b84ed88

commit r14-11727-gce3f523f9cb4c20704bc5f41b8fbc34b5b84ed88
Author: Iain Sandoe 
Date:   Sun Aug 18 22:54:50 2024 +0100

c++, coroutines: Rework handling of throwing_cleanups [PR102051].

In the fix for PR95822 (r11-7402) we set throwing_cleanup false in the top
level of the coroutine transform code.  However, as the current PR shows,
that is not sufficient.

Any use of cxx_maybe_build_cleanup() can reset the flag, which causes the
check_return_expr () logic to try to add a guard variable and set it.

For the coroutine code, we need to handle the cleanups separately, since
the responsibility for them changes after the first resume point, which
we handle in the ramp exception processing.

Fix this by forcing the "throwing_cleanup" flag false right before the
processing of the return expression.

PR c++/102051

gcc/cp/ChangeLog:

* coroutines.cc
(cp_coroutine_transform::build_ramp_function): Handle
"throwing_cleanup" here instead of ...
(cp_coroutine_transform::apply_transforms): ... here.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr102051.C: New test.

Signed-off-by: Iain Sandoe 
(cherry picked from commit f0315f7a325ffccb446fe378fcdfccda6eead8ba)

Diff:
---
 gcc/cp/coroutines.cc   | 15 ---
 gcc/testsuite/g++.dg/coroutines/pr102051.C | 16 
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 00a016d1bd31..82ba96f65674 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4632,17 +4632,6 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   TREE_OPERAND (body_start, 0) = push_stmt_list ();
 }
 
-  /* If the original function has a return value with a non-trivial DTOR
- and the body contains a var with a DTOR that might throw, the decl is
- marked "throwing_cleanup".
- We do not [in the ramp, which is synthesised here], use any body var
- types with DTORs that might throw.
- The original body is transformed into the actor function which only
- contains void returns, and is also wrapped in a try-catch block.
- So (a) the 'throwing_cleanup' is not correct for the ramp and (b) we do
- not need to transfer it to the actor which only contains void returns.  */
-  cp_function_chain->throwing_cleanup = false;
-
   /* Create the coro frame type, as far as it can be known at this stage.
  1. Types we already know.  */
 
@@ -5270,6 +5259,10 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
  either as the return value (if it's the same type) or to the CTOR
  for an object of the return type.  */
 
+  /* We must manage the cleanups ourselves, because the responsibility for
+ them changes after the initial suspend.  However, any use of
+ cxx_maybe_build_cleanup () can set the throwing_cleanup flag.  */
+  cp_function_chain->throwing_cleanup = false;
   if (same_type_p (gro_type, fn_return_type))
 r = void_ramp_p ? NULL_TREE : DECL_RESULT (orig);
   else
diff --git a/gcc/testsuite/g++.dg/coroutines/pr102051.C 
b/gcc/testsuite/g++.dg/coroutines/pr102051.C
new file mode 100644
index ..bba98b691cc2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr102051.C
@@ -0,0 +1,16 @@
+#include 
+
+struct Foo {
+~Foo() noexcept(false); // true succeeds
+struct promise_type {
+Foo get_return_object() { return {}; }
+std::suspend_never initial_suspend() { return {}; }
+void return_void() {}
+void unhandled_exception() {}
+std::suspend_always final_suspend() noexcept { return {}; }
+};
+};
+
+Foo bar() {
+co_return;
+}


[gcc r14-11728] c++, coroutines: Look through initial_await target exprs [PR110635].

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:4042cecd6245dc773fc150d5fd839968674e4500

commit r14-11728-g4042cecd6245dc773fc150d5fd839968674e4500
Author: Iain Sandoe 
Date:   Mon Aug 19 20:50:54 2024 +0100

c++, coroutines: Look through initial_await target exprs [PR110635].

In the case that the initial awaiter returns an object, the initial await
can be a target expression and we need to look at its initializer to cast
the await_resume() to void and to wrap in a compound expression that sets
the initial_await_resume_called flag.

PR c++/110635

gcc/cp/ChangeLog:

* coroutines.cc
(cp_coroutine_transform::wrap_original_function_body): Look through
initial await target expressions to find the actual co_await_expr
that we need to update.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr110635.C: New test.

Signed-off-by: Iain Sandoe 
(cherry picked from commit c442a9b78bdbebdbcb4a8f91bc36961eb732fbdf)

Diff:
---
 gcc/cp/coroutines.cc   |  8 +++-
 gcc/testsuite/g++.dg/coroutines/pr110635.C | 72 ++
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 82ba96f65674..ee0fbc454e6e 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4442,7 +4442,13 @@ coro_rewrite_function_body (location_t fn_start, tree 
fnbody, tree orig,
 a reference type, look past the indirection.  */
  if (INDIRECT_REF_P (initial_await))
initial_await = TREE_OPERAND (initial_await, 0);
- tree vec = TREE_OPERAND (initial_await, 3);
+ /* In the case that the initial_await returns a target expression
+we might need to look through that to update the await expr.  */
+ tree iaw = initial_await;
+ if (TREE_CODE (iaw) == TARGET_EXPR)
+   iaw = TARGET_EXPR_INITIAL (iaw);
+ gcc_checking_assert (TREE_CODE (iaw) == CO_AWAIT_EXPR);
+ tree vec = TREE_OPERAND (iaw, 3);
  tree aw_r = TREE_VEC_ELT (vec, 2);
  aw_r = convert_to_void (aw_r, ICV_STATEMENT, tf_warning_or_error);
  tree update = build2 (MODIFY_EXPR, boolean_type_node, i_a_r_c,
diff --git a/gcc/testsuite/g++.dg/coroutines/pr110635.C 
b/gcc/testsuite/g++.dg/coroutines/pr110635.C
new file mode 100644
index ..ea4e0e853eb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr110635.C
@@ -0,0 +1,72 @@
+
+#define CASE 0
+#include 
+#include 
+
+struct Coroutine {
+
+struct promise_type;
+
+using handler_type = std::coroutine_handle;
+
+struct initial_suspend_awaiter {
+
+bool await_ready() noexcept {
+std::cout << "await_ready" << std::endl;
+return false;
+}
+
+void await_suspend(handler_type h) noexcept {
+std::cout << "await_suspend" << std::endl;
+}
+
+#if CASE == 0
+struct await_resume_return_object {
+await_resume_return_object() noexcept {
+std::cout << "await_resume_return_object" << std::endl;
+}
+
+~await_resume_return_object() noexcept {
+std::cout << "~await_resume_return_object" << std::endl;
+}
+};
+#elif CASE == 1
+using await_resume_return_object = struct{};
+#elif CASE == 2
+using await_resume_return_object = int;
+#else
+using await_resume_return_object = void;
+#endif
+await_resume_return_object await_resume() noexcept {
+std::cout << "await_resume" << std::endl;
+#if CASE == 0 || CASE == 1 || CASE == 2
+return {};
+#endif
+}
+
+initial_suspend_awaiter() noexcept {
+std::cout << "initial_suspend_awaiter" << std::endl;
+}
+
+~initial_suspend_awaiter() noexcept {
+std::cout << "~initial_suspend_awaiter" << std::endl;
+}
+};
+
+struct promise_type {
+void return_void() noexcept {}
+void unhandled_exception() noexcept { std::terminate();}
+initial_suspend_awaiter initial_suspend() noexcept { return {}; }
+std::suspend_never final_suspend() noexcept { return {}; }
+Coroutine get_return_object() {
+return Coroutine{handler_type::from_promise(*this)};
+}
+};
+
+handler_type handler;
+};
+
+int main() {
+auto coro = []()->Coroutine { co_return; }();
+coro.handler.resume();
+}


[gcc r14-11729] c++/coros: do not assume coros don't nest [PR113457]

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:805b9914846a1228b84a3c3dd8f9ba2f21f9ff59

commit r14-11729-g805b9914846a1228b84a3c3dd8f9ba2f21f9ff59
Author: Arsen Arsenović 
Date:   Fri Aug 23 20:19:05 2024 +0200

c++/coros: do not assume coros don't nest [PR113457]

In the testcase presented in the PR, during template expansion, an
tsubst of an operand causes a lambda coroutine to be processed, causing
it to get an initial suspend and final suspend.  The code for assigning
awaitable var names (get_awaitable_var) assumed that the sequence Is ->
Is -> Fs -> Fs is impossible (i.e. that one could only 'open' one
coroutine before closing it at a time), and reset the counter used for
unique numbering each time a final suspend occured.  This assumption is
false in a few cases, usually when lambdas are involved.

Instead of storing this counter in a static-storage variable, we can
store it in coroutine_info.  This struct is local to each function, so
we don't need to worry about "cross-contamination" nor resetting.

PR c++/113457

gcc/cp/ChangeLog:

* coroutines.cc (struct coroutine_info): Add integer field
awaitable_number.  This is a counter used for assigning unique
names to awaitable temporaries.
(get_awaitable_var): Use awaitable_number from coroutine_info
instead of the static int awn.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr113457-1.C: New test.
* g++.dg/coroutines/pr113457.C: New test.

(cherry picked from commit 5cca7517c5868b7b9aa13992145eb6082ac5d5b9)

Diff:
---
 gcc/cp/coroutines.cc |  19 ++-
 gcc/testsuite/g++.dg/coroutines/pr113457-1.C |  25 
 gcc/testsuite/g++.dg/coroutines/pr113457.C   | 178 +++
 3 files changed, 216 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index ee0fbc454e6e..953297c3c496 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -95,6 +95,10 @@ struct GTY((for_user)) coroutine_info
   tree return_void;   /* The expression for p.return_void() if it exists.  */
   location_t first_coro_keyword; /* The location of the keyword that made this
function into a coroutine.  */
+
+  /* Temporary variable number assigned by get_awaitable_var.  */
+  int awaitable_number = 0;
+
   /* Flags to avoid repeated errors for per-function issues.  */
   bool coro_ret_type_error_emitted;
   bool coro_promise_error_emitted;
@@ -981,15 +985,18 @@ enum suspend_point_kind {
 static tree
 get_awaitable_var (suspend_point_kind suspend_kind, tree v_type)
 {
-  static int awn = 0;
+  auto cinfo = get_coroutine_info (current_function_decl);
+  gcc_checking_assert (cinfo);
   char *buf;
   switch (suspend_kind)
 {
-  default: buf = xasprintf ("Aw%d", awn++); break;
-  case CO_YIELD_SUSPEND_POINT: buf =  xasprintf ("Yd%d", awn++); break;
-  case INITIAL_SUSPEND_POINT: buf =  xasprintf ("Is"); break;
-  case FINAL_SUSPEND_POINT: buf =  xasprintf ("Fs"); awn = 0; break;
-  }
+default: buf = xasprintf ("Aw%d", cinfo->awaitable_number++); break;
+case CO_YIELD_SUSPEND_POINT:
+  buf = xasprintf ("Yd%d", cinfo->awaitable_number++);
+  break;
+case INITIAL_SUSPEND_POINT: buf = xasprintf ("Is"); break;
+case FINAL_SUSPEND_POINT: buf = xasprintf ("Fs"); break;
+}
   tree ret = get_identifier (buf);
   free (buf);
   ret = build_lang_decl (VAR_DECL, ret, v_type);
diff --git a/gcc/testsuite/g++.dg/coroutines/pr113457-1.C 
b/gcc/testsuite/g++.dg/coroutines/pr113457-1.C
new file mode 100644
index ..fcf67e15271c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr113457-1.C
@@ -0,0 +1,25 @@
+// https://gcc.gnu.org/PR113457
+#include 
+
+struct coro
+{
+  struct promise_type
+  {
+std::suspend_never initial_suspend ();
+std::suspend_never final_suspend () noexcept;
+void return_void ();
+void unhandled_exception ();
+coro get_return_object ();
+  };
+};
+
+struct not_quite_suspend_never : std::suspend_never
+{};
+
+coro
+foo ()
+{
+  co_await std::suspend_never{},
+[] () -> coro { co_return; },
+co_await not_quite_suspend_never{};
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr113457.C 
b/gcc/testsuite/g++.dg/coroutines/pr113457.C
new file mode 100644
index ..add45a2f8921
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr113457.C
@@ -0,0 +1,178 @@
+// https://gcc.gnu.org/PR113457
+namespace std {
+template  _Up __declval(int);
+template  auto declval() noexcept -> decltype(__declval<_Tp>(0));
+template  struct remove_cv {
+  using type = __remove_cv(_Tp);
+};
+template  using remove_cv_t = typename remove_cv<_Tp>::type;
+template  struct remove_reference {
+  using type = __remove_reference(_Tp);
+};
+template 
+using remove_reference_t = typename remove_reference<_Tp>::type;
+template  inline constexpr bool is_a

[gcc r14-11730] c++, coroutines: The frame pointer is used in the helpers [PR116482].

2025-05-05 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:b2fa7e036e72fa0ed63df602cebd4005b078336e

commit r14-11730-gb2fa7e036e72fa0ed63df602cebd4005b078336e
Author: Iain Sandoe 
Date:   Mon Aug 26 14:09:40 2024 +0100

c++, coroutines: The frame pointer is used in the helpers [PR116482].

We have a bogus warning about the coroutine state frame pointers
being apparently unused in the resume and destroy functions.  Fixed
by making the parameters DECL_ARTIFICIAL.

PR c++/116482

gcc/cp/ChangeLog:

* coroutines.cc
(coro_build_actor_or_destroy_function): Make the parameter
decls DECL_ARTIFICIAL.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr116482.C: New test.

Signed-off-by: Iain Sandoe 
(cherry picked from commit 8d6d6c864442a1cc987b3e6bcb1d903ceb975e4a)

Diff:
---
 gcc/cp/coroutines.cc   |  1 +
 gcc/testsuite/g++.dg/coroutines/pr116482.C | 30 ++
 2 files changed, 31 insertions(+)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 953297c3c496..8bb46ff5c990 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4226,6 +4226,7 @@ coro_build_actor_or_destroy_function (tree orig, tree 
fn_type,
 
   tree id = get_identifier ("frame_ptr");
   tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
+  DECL_ARTIFICIAL (fp) = true;
   DECL_CONTEXT (fp) = fn;
   DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
   DECL_ARGUMENTS (fn) = fp;
diff --git a/gcc/testsuite/g++.dg/coroutines/pr116482.C 
b/gcc/testsuite/g++.dg/coroutines/pr116482.C
new file mode 100644
index ..702d1e235bb7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr116482.C
@@ -0,0 +1,30 @@
+// Override default options.
+// { dg-options "-std=c++20 -fno-exceptions -Wall -Wextra" }
+
+#include 
+
+struct SuspendNever {
+bool await_ready();
+void await_suspend(std::coroutine_handle<>);
+void await_resume();
+};
+
+struct Coroutine;
+
+struct PromiseType {
+Coroutine get_return_object();
+SuspendNever initial_suspend();
+SuspendNever final_suspend();
+#if __cpp_exceptions
+void unhandled_exception() { /*std::terminate();*/ };
+#endif
+void return_void();
+};
+
+struct Coroutine {
+using promise_type = PromiseType;
+};
+
+Coroutine __async_test_input_basic() {
+co_return;
+}


[gcc r15-9622] ipa/120006 - wrong code with IPA PTA

2025-05-05 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:169ad482497ae9c672a825050b8f4b6d54cd5d24

commit r15-9622-g169ad482497ae9c672a825050b8f4b6d54cd5d24
Author: Richard Biener 
Date:   Wed Apr 30 10:01:47 2025 +0200

ipa/120006 - wrong code with IPA PTA

When PTA gets support for special-handling more builtins in
find_func_aliases the corresponding code in find_func_clobbers
needs updating as well since for unhandled cases it assumes
the former will populate ESCAPED accordingly.  The following
fixes a few omissions, the testcase runs into the missing strdup
handling.  I believe the more advanced handling using modref
results and fnspecs opened a larger gap, the proper fix is to
merge both functions, gating the clobber/use part on a parameter
to avoid diverging.

PR ipa/120006
* tree-ssa-structalias.cc (find_func_clobbers): Handle
strdup, strndup, realloc, index, strchr, strrchr, memchr,
strstr, strpbrk builtins like find_func_aliases does.

* gcc.dg/torture/pr120006.c: New testcase.

(cherry picked from commit a85b89e26b1f50997701eb428c2dd71668f216ff)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr120006.c | 31 
 gcc/tree-ssa-structalias.cc | 36 +
 2 files changed, 67 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr120006.c 
b/gcc/testsuite/gcc.dg/torture/pr120006.c
new file mode 100644
index ..c067f0ef9ca0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120006.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fipa-pta" } */
+
+char *b;
+int f = 1;
+
+char *xstrdup(char *i) {
+  char *c = __builtin_strdup(i);
+  if (!c)
+__builtin_exit(1);
+  return c;
+}
+
+int main() {
+  char g;
+  char h[8];
+
+  for (int i = 0; i < 2; i++) {
+char c = *__builtin_strdup("");
+b = &g;
+
+if (f) {
+  h[0] = '-';
+  h[1] = 'a';
+  h[2] = '\0';
+  b = xstrdup(h);
+   }
+  }
+  if (__builtin_strcmp(b, "-a") != 0)
+__builtin_abort();
+}
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index f79b54284c64..3ad0c69930c7 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -5583,6 +5583,42 @@ find_func_clobbers (struct function *fn, gimple *origt)
  process_ipa_clobber (fi, gimple_call_arg (t, 2));
  return;
}
+ /* The following functions use what their first argument
+points to.  */
+ case BUILT_IN_STRDUP:
+ case BUILT_IN_STRNDUP:
+ case BUILT_IN_REALLOC:
+ case BUILT_IN_INDEX:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_STRRCHR:
+ case BUILT_IN_MEMCHR:
+   {
+ tree src = gimple_call_arg (t, 0);
+ get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
+ lhs = get_function_part_constraint (fi, fi_uses);
+ struct constraint_expr *rhsp;
+ FOR_EACH_VEC_ELT (rhsc, i, rhsp)
+   process_constraint (new_constraint (lhs, *rhsp));
+ return;
+   }
+ /* The following functions use what their first and second argument
+point to.  */
+ case BUILT_IN_STRSTR:
+ case BUILT_IN_STRPBRK:
+   {
+ tree src = gimple_call_arg (t, 0);
+ get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
+ lhs = get_function_part_constraint (fi, fi_uses);
+ struct constraint_expr *rhsp;
+ FOR_EACH_VEC_ELT (rhsc, i, rhsp)
+   process_constraint (new_constraint (lhs, *rhsp));
+ rhsc.truncate (0);
+ src = gimple_call_arg (t, 1);
+ get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
+ FOR_EACH_VEC_ELT (rhsc, i, rhsp)
+   process_constraint (new_constraint (lhs, *rhsp));
+ return;
+   }
  /* The following functions neither read nor clobber memory.  */
  case BUILT_IN_ASSUME_ALIGNED:
  case BUILT_IN_FREE: