[gcc r14-11504] tree-optimization/98845 - ICE with tail-merging and DCE/DSE disabled

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:9d516fb8ea547fa7b0ddea1f56cdb44a48f93663

commit r14-11504-g9d516fb8ea547fa7b0ddea1f56cdb44a48f93663
Author: Richard Biener 
Date:   Mon Feb 17 15:53:11 2025 +0100

tree-optimization/98845 - ICE with tail-merging and DCE/DSE disabled

The following shows that tail-merging will make dead SSA defs live
in paths where it wasn't before, possibly introducing UB or as
in this case, uses of abnormals that eventually fail coalescing
later.  The fix is to register such defs for stmt comparison.

PR tree-optimization/98845
* tree-ssa-tail-merge.cc (stmt_local_def): Consider a
def with no uses not local.

* gcc.dg/pr98845.c: New testcase.
* gcc.dg/pr81192.c: Adjust.

(cherry picked from commit 6b8a8c9fd68c5dabaec5ddbc25efeade44f37a14)

Diff:
---
 gcc/testsuite/gcc.dg/pr81192.c |  6 +-
 gcc/testsuite/gcc.dg/pr98845.c | 33 +
 gcc/tree-ssa-tail-merge.cc |  8 
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c
index c46ac18fd9af..87a7a7a19c80 100644
--- a/gcc/testsuite/gcc.dg/pr81192.c
+++ b/gcc/testsuite/gcc.dg/pr81192.c
@@ -25,12 +25,16 @@ void __GIMPLE(ssa, startwith("pre")) fn2   ()
   if (j_6(D) != _Literal (int)2147483647)
 goto __BB4;
   else
-goto __BB5;
+goto __BB9;
 
   __BB(4):
   iftmp2_8 = j_6(D) + _Literal (int)1;
   goto __BB5;
 
+  __BB(9):
+  iftmp2_8 = j_6(D) + _Literal (int)1;
+  goto __BB5;
+
   __BB(5):
   b_lsm6_10 = _Literal (int)2147483647;
   goto __BB6;
diff --git a/gcc/testsuite/gcc.dg/pr98845.c b/gcc/testsuite/gcc.dg/pr98845.c
new file mode 100644
index ..074c979678f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr98845.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dce -fno-tree-dse" } */
+
+int n;
+
+__attribute__ ((returns_twice)) void
+foo (void);
+
+void
+bar (void);
+
+void
+quux (int x)
+{
+  if (x)
+++x;
+  else
+{
+  if (n)
+{
+  x = 1;
+  foo ();
+}
+  else
+bar ();
+
+  if (n)
+{
+  ++x;
+  ++n;
+}
+}
+}
diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc
index c8b4a79294d7..c87b2f4dd152 100644
--- a/gcc/tree-ssa-tail-merge.cc
+++ b/gcc/tree-ssa-tail-merge.cc
@@ -336,10 +336,13 @@ stmt_local_def (gimple *stmt)
 
   def_bb = gimple_bb (stmt);
 
+  bool any_use = false;
   FOR_EACH_IMM_USE_FAST (use_p, iter, val)
 {
   if (is_gimple_debug (USE_STMT (use_p)))
continue;
+
+  any_use = true;
   bb = gimple_bb (USE_STMT (use_p));
   if (bb == def_bb)
continue;
@@ -351,6 +354,11 @@ stmt_local_def (gimple *stmt)
   return false;
 }
 
+  /* When there is no use avoid making the stmt live on other paths.
+ This can happen with DCE disabled or not done as seen in PR98845.  */
+  if (!any_use)
+return false;
+
   return true;
 }


[gcc r14-11502] tree-optimization/87984 - hard register assignments not preserved

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:3b84ac64816557e6c953984f096e0995f946e063

commit r14-11502-g3b84ac64816557e6c953984f096e0995f946e063
Author: Richard Biener 
Date:   Fri Feb 28 10:36:11 2025 +0100

tree-optimization/87984 - hard register assignments not preserved

The following disables redundant store elimination to hard register
variables which isn't valid.

PR tree-optimization/87984
* tree-ssa-dom.cc (dom_opt_dom_walker::optimize_stmt): Do
not perform redundant store elimination to hard register
variables.
* tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_stmt):
Likewise.

* gcc.target/i386/pr87984.c: New testcase.

(cherry picked from commit 535115caaf97f5201fb528f67f15b4c52be5619d)

Diff:
---
 gcc/testsuite/gcc.target/i386/pr87984.c | 23 +++
 gcc/tree-ssa-dom.cc |  4 +++-
 gcc/tree-ssa-sccvn.cc   |  2 ++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/pr87984.c 
b/gcc/testsuite/gcc.target/i386/pr87984.c
new file mode 100644
index ..39a6a7480f9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr87984.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+__attribute__((noipa))
+int f(void)
+{
+  int o = 0;
+  for (int i = 0; i < 3; i++)
+{
+  register int a asm("eax");
+  a = 1;
+  asm("add %1, %0" : "+r"(o) : "r"(a));
+  asm("xor %%eax, %%eax" ::: "eax");
+}
+  return o;
+}
+
+int main()
+{
+  if (f() != 3)
+__builtin_abort();
+  return 0;
+}
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index 73264852ebd9..544e4ca7c7e9 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -2455,7 +2455,9 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, 
gimple_stmt_iterator *si,
 
   /* Perform simple redundant store elimination.  */
   if (gimple_assign_single_p (stmt)
- && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
+ && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME
+ && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
+ || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt
{
  tree lhs = gimple_assign_lhs (stmt);
  tree rhs = gimple_assign_rhs1 (stmt);
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index ff27b75313e0..debfd1d04355 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -7084,6 +7084,8 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, 
gimple_stmt_iterator *gsi)
   if (gimple_assign_single_p (stmt)
   && !gimple_has_volatile_ops (stmt)
   && !is_gimple_reg (gimple_assign_lhs (stmt))
+  && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
+ || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt)))
   && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
  || is_gimple_min_invariant (gimple_assign_rhs1 (stmt
 {


[gcc r14-11501] c++/79786 - bougs invocation of DATA_ABI_ALIGNMENT macro

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:931277d91f29eab79e2d4008f0f69c809df95bcb

commit r14-11501-g931277d91f29eab79e2d4008f0f69c809df95bcb
Author: Richard Biener 
Date:   Mon Feb 3 11:27:20 2025 +0100

c++/79786 - bougs invocation of DATA_ABI_ALIGNMENT macro

The first argument is supposed to be a type, not a decl.

PR c++/79786
gcc/cp/
* rtti.cc (emit_tinfo_decl): Fix DATA_ABI_ALIGNMENT invocation.

(cherry picked from commit 6ec19825b4e72611cdbd4749feed67b61392aa81)

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

diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
index ed69606f4ddc..5e091602cf35 100644
--- a/gcc/cp/rtti.cc
+++ b/gcc/cp/rtti.cc
@@ -1739,7 +1739,8 @@ emit_tinfo_decl (tree decl)
   /* Avoid targets optionally bumping up the alignment to improve
 vector instruction accesses, tinfo are never accessed this way.  */
 #ifdef DATA_ABI_ALIGNMENT
-  SET_DECL_ALIGN (decl, DATA_ABI_ALIGNMENT (decl, TYPE_ALIGN (TREE_TYPE 
(decl;
+  SET_DECL_ALIGN (decl, DATA_ABI_ALIGNMENT (TREE_TYPE (decl),
+   TYPE_ALIGN (TREE_TYPE (decl;
   DECL_USER_ALIGN (decl) = true;
 #endif
   return true;


[gcc r14-11500] middle-end/66279 - gimplification clobbers shared asm constraints

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:12b536c17d28500fa9ad32563ae6088726162051

commit r14-11500-g12b536c17d28500fa9ad32563ae6088726162051
Author: Richard Biener 
Date:   Fri Feb 28 09:58:36 2025 +0100

middle-end/66279 - gimplification clobbers shared asm constraints

When the C++ frontend clones a CTOR we do not copy ASM_EXPR constraints
fully as walk_tree does not recurse to TREE_PURPOSE of TREE_LIST nodes.
At this point doing that seems too dangerous so the following instead
avoids gimplification of ASM_EXPRs to clobber the shared constraints
and unshares it there, like it also unshares TREE_VALUE when it
re-writes a "+" output constraint to separate "=" output and matching
input constraint.

PR middle-end/66279
* gimplify.cc (gimplify_asm_expr): Copy TREE_PURPOSE before
rewriting it for "+" processing.

* g++.dg/pr66279.C: New testcase.

(cherry picked from commit 95f5d6cc17e7d6b689674756c62b6b5e1284afd0)

Diff:
---
 gcc/gimplify.cc|  1 +
 gcc/testsuite/g++.dg/pr66279.C | 23 +++
 2 files changed, 24 insertions(+)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 32ecb0cffe5d..a4972d3f471e 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -7084,6 +7084,7 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p)
  /* Turn the in/out constraint into an output constraint.  */
  char *p = xstrdup (constraint);
  p[0] = '=';
+ TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link));
  TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
 
  /* And add a matching input constraint.  */
diff --git a/gcc/testsuite/g++.dg/pr66279.C b/gcc/testsuite/g++.dg/pr66279.C
new file mode 100644
index ..c878044a83b3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr66279.C
@@ -0,0 +1,23 @@
+// { dg-do run }
+
+struct A {};
+
+struct B : public virtual A
+{
+  B();
+};
+
+B::B()
+{
+  unsigned int x = 42;
+
+  __asm__ __volatile__ ("" : "+r"(x));
+
+  if (x != 42)
+__builtin_abort ();
+}
+
+int main()
+{
+  B b;
+}


[gcc r14-11505] middle-end/101478 - ICE with degenerate address during gimplification

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:a57c877f8899ac9171eaeafa7641ac79cce96f89

commit r14-11505-ga57c877f8899ac9171eaeafa7641ac79cce96f89
Author: Richard Biener 
Date:   Wed Jul 31 10:07:45 2024 +0200

middle-end/101478 - ICE with degenerate address during gimplification

When we gimplify &MEM[0B + 4] we are re-folding the address in case
types are not canonical which ends up with a constant address that
recompute_tree_invariant_for_addr_expr ICEs on.  Properly guard
that call.

PR middle-end/101478
* gimplify.cc (gimplify_addr_expr): Check we still have an
ADDR_EXPR before calling recompute_tree_invariant_for_addr_expr.

* gcc.dg/pr101478.c: New testcase.

(cherry picked from commit 33ead6400ad59d4b38fa0527a9a7b53a28114ab7)

Diff:
---
 gcc/gimplify.cc |  3 ++-
 gcc/testsuite/gcc.dg/pr101478.c | 11 +++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index a4972d3f471e..b85c6ffbe9b8 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -6936,7 +6936,8 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p)
*expr_p = build_fold_addr_expr (op0);
 
   /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
-  recompute_tree_invariant_for_addr_expr (*expr_p);
+  if (TREE_CODE (*expr_p) == ADDR_EXPR)
+   recompute_tree_invariant_for_addr_expr (*expr_p);
 
   /* If we re-built the ADDR_EXPR add a conversion to the original type
  if required.  */
diff --git a/gcc/testsuite/gcc.dg/pr101478.c b/gcc/testsuite/gcc.dg/pr101478.c
new file mode 100644
index ..527620ea0f11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr101478.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct obj {
+  int n;
+  int l;
+};
+int main()
+{
+  (struct obj *)((char *)(__SIZE_TYPE__)({ 0; }) - (char *)&((struct obj 
*)0)->l);
+}


[gcc/devel/omp/gcc-14] Reduce iteration counts for gcc.dg/vect/tsvc tests.

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:37cf0b5aba6e3e9d585a79fafe2286d8fc0a2b72

commit 37cf0b5aba6e3e9d585a79fafe2286d8fc0a2b72
Author: Joern Rennecke 
Date:   Mon Jul 22 11:02:16 2024 +0100

Reduce iteration counts for gcc.dg/vect/tsvc tests.

testsuite/
* gcc.dg/vect/tsvc/tsvc.h (iterations): Allow to override,
default to 10.
(get_expected_result): Add values for iterations counts
10, 256 and 3200.
(run): Add code to output values for new iterations counts.
* gcc.dg/vect/tsvc/vect-tsvc-s1119.c (dg-additional-options):
Add -Diterations=LEN_2D .
* gcc.dg/vect/tsvc/vect-tsvc-s115.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s119.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s125.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s2102.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s2233.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s2275.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s231.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s235.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s176.c: (dg-additional-options):
Add -Diterations=3200 .
[!run_expensive_tests]: dg-additional-options "-DTRUNCATE_TEST" .
[TRUNCATE_TEST]: Set m to 32.

(cherry picked from commit 8fac69a2dbff98ebe1feb87faba0d9b81a173c40)

Diff:
---
 gcc/testsuite/ChangeLog.omp  |  25 ++
 gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h| 352 ++-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s1119.c |   4 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s115.c  |   4 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s119.c  |   4 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s125.c  |   4 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s176.c  |  13 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2102.c |   2 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2233.c |   4 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2275.c |   4 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s231.c  |   4 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s235.c  |   4 +-
 12 files changed, 404 insertions(+), 20 deletions(-)

diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 0c39103e3b33..231af59dbcef 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,28 @@
+2025-04-02  Thomas Schwinge  
+
+   Backported from trunk:
+   2024-08-07  Joern Rennecke  
+
+   * gcc.dg/vect/tsvc/tsvc.h (iterations): Allow to override,
+   default to 10.
+   (get_expected_result): Add values for iterations counts
+   10, 256 and 3200.
+   (run): Add code to output values for new iterations counts.
+   * gcc.dg/vect/tsvc/vect-tsvc-s1119.c (dg-additional-options):
+   Add -Diterations=LEN_2D .
+   * gcc.dg/vect/tsvc/vect-tsvc-s115.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s119.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s125.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s2102.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s2233.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s2275.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s231.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s235.c: Likewise.
+   * gcc.dg/vect/tsvc/vect-tsvc-s176.c: (dg-additional-options):
+   Add -Diterations=3200 .
+   [!run_expensive_tests]: dg-additional-options "-DTRUNCATE_TEST" .
+   [TRUNCATE_TEST]: Set m to 32.
+
 2025-03-30  Tobias Burnus  
 
Backported from master:
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h 
b/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h
index d910c384fc83..cc02e4cacba1 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h
@@ -1,7 +1,10 @@
 /*  This file is distributed under the University of Illinois Open Source
 License. See license.txt for details.  */
 
-#define iterations 1
+#ifndef iterations
+#define iterations 10
+/* Was: #define iterations 1 */
+#endif
 #define LEN_1D 32000
 #define LEN_2D 256
 #define ARRAY_ALIGNMENT 64
@@ -1093,7 +1096,11 @@ real_t calc_checksum(const char * name)
 
 real_t get_expected_result(const char * name) 
 {
-if (!strcmp(name, "s000")) {
+if (!name) {
+fprintf(stderr, "NULL name passed to expected_result.\n");
+exit(1);
+#if iterations == 1
+} else if (!strcmp(name, "s000")) {
return 512075584.f;
 } else if (!strcmp(name, "s111")) {
return 32000.410156f;
@@ -1395,6 +1402,334 @@ real_t get_expected_result(const char * name)
return 1.644824f;
 } else if (!strcmp(name, "vbor")) {
return 31924.046875f;
+#elif iterations == 10
+} else if (!strcmp (name, "s000")) {
+   return 512066944.00f;
+} else if (!strcmp (name, "s")) {
+   return 13.352139f;
+} else if (!strcmp (name, "s1112")) {
+   return 32008.869141f;
+} else if (!strcmp (name, "s1113")) {

[gcc/devel/omp/gcc-14] Fix PR testsuite/116271, gcc.dg/vect/tsvc/vect-tsvc-s176.c fails

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:86feb06ab181b1578d06fae7399427f7b1f3fb21

commit 86feb06ab181b1578d06fae7399427f7b1f3fb21
Author: Joern Rennecke 
Date:   Wed Aug 28 01:46:25 2024 +0100

Fix PR testsuite/116271, gcc.dg/vect/tsvc/vect-tsvc-s176.c fails

gcc/testsuite:
PR testsuite/116271
* gcc.dg/vect/tsvc/vect-tsvc-s176.c [TRUNCATE_TEST]: Make sure
that m stays the same as the loop bound of the middle loop.
* gcc.dg/vect/tsvc/tsvc.h (get_expected_result)  
[TRUNCATE_TEST]:
Adjust expected value.

(cherry picked from commit beb94f5979953969593a2387561cdbc8fedfaeb1)

Diff:
---
 gcc/testsuite/ChangeLog.omp |  9 +
 gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h   |  2 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s176.c | 18 ++
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 231af59dbcef..5f4a5e53cce9 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,5 +1,14 @@
 2025-04-02  Thomas Schwinge  
 
+   Backported from trunk:
+   2024-08-28  Joern Rennecke  
+
+   PR testsuite/116271
+   * gcc.dg/vect/tsvc/vect-tsvc-s176.c [TRUNCATE_TEST]: Make sure
+   that m stays the same as the loop bound of the middle loop.
+   * gcc.dg/vect/tsvc/tsvc.h (get_expected_result)  [TRUNCATE_TEST]:
+   Adjust expected value.
+
Backported from trunk:
2024-08-07  Joern Rennecke  
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h 
b/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h
index cc02e4cacba1..4d295d1ec296 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/tsvc.h
@@ -1727,7 +1727,7 @@ real_t get_expected_result(const char * name)
 #ifndef TRUNCATE_TEST
 return 32021.121094f;
 #else /* TRUNCATE_TEST */
-return 32024.082031f;
+return 32023.751953f;
 #endif /* TRUNCATE_TEST */
 #endif /* iterations */
 } else {
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s176.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s176.c
index 6e9580582d54..626692bcb81d 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s176.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s176.c
@@ -15,18 +15,20 @@ real_t s176(struct args_t * func_args)
 
 initialise_arrays(__func__);
 
-int m = LEN_1D/2;
 #ifdef TRUNCATE_TEST
-/* Do something equivalent to if (1) which the compiler is unlikely to
-   figure out.
-   FUNC_ARGS is in the caller's frame, so it shouldn't be between A and B.
- */
-if ((void *)func_args <= (void *)a || (void *)func_args >= (void *)b)
-   m = 32;
+/* Reduce the iteration counts without changing what is a variable and
+   what is a constant expression.
+   32000/25 == 640, i.e. it still has a nice power of two factor, but is
+   not a power of two itself, and still somewhat large-ish, so hopefully
+   this won't perturb the vectorizer decisions much.  */
+#define M_CONST LEN_1D/50
+#else
+#define M_CONST LEN_1D/2
 #endif
+int m = M_CONST;
 
 for (int nl = 0; nl < 4*(10*iterations/LEN_1D); nl++) {
-for (int j = 0; j < (LEN_1D/2); j++) {
+for (int j = 0; j < (M_CONST); j++) {
 for (int i = 0; i < m; i++) {
 a[i] += b[i+m-j-1] * c[j];
 }


[gcc r15-9144] testsuite: arm: Fix dg-final in short-vfp-1.c [PR119556]

2025-04-02 Thread Christophe Lyon via Gcc-cvs
https://gcc.gnu.org/g:df225ae29a147ae40bb44ba14ee979b67fd19c8e

commit r15-9144-gdf225ae29a147ae40bb44ba14ee979b67fd19c8e
Author: Christophe Lyon 
Date:   Mon Mar 31 19:00:44 2025 +

testsuite: arm: Fix dg-final in short-vfp-1.c [PR119556]

Recent syntactic fixes enabled the test, but the result was failing.

It turns out it was missing a space between the register arguments in
the scan-assembler-times directives.

gcc/testsuite/ChangeLog:

PR target/119556
* gcc.target/arm/short-vfp-1.c: Add missing spaces.

Diff:
---
 gcc/testsuite/gcc.target/arm/short-vfp-1.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/short-vfp-1.c 
b/gcc/testsuite/gcc.target/arm/short-vfp-1.c
index 18d38a580377..f6866c4f6012 100644
--- a/gcc/testsuite/gcc.target/arm/short-vfp-1.c
+++ b/gcc/testsuite/gcc.target/arm/short-vfp-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-require-effective-target arm_vfp_ok }
+/* { dg-require-effective-target arm_vfp_ok } */
 /* { dg-add-options arm_vfp } */
 
 int
@@ -38,8 +38,8 @@ test_sihi (short x)
   return (int)x;
 }
 
-/* { dg-final { scan-assembler-times {vcvt\.s32\.f32\ts[0-9]+,s[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {vcvt\.f32\.s32\ts[0-9]+,s[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {vmov\tr[0-9]+,s[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {vmov\ts[0-9]+,r[0-9]+} 2 } } */
-/* { dg-final { scan-assembler-times {sxth\tr[0-9]+,r[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vcvt\.s32\.f32\ts[0-9]+, s[0-9]+} 2 } } 
*/
+/* { dg-final { scan-assembler-times {vcvt\.f32\.s32\ts[0-9]+, s[0-9]+} 2 } } 
*/
+/* { dg-final { scan-assembler-times {vmov\tr[0-9]+, s[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vmov\ts[0-9]+, r[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {sxth\tr[0-9]+, r[0-9]+} 2 } } */


[gcc/devel/rust/master] gccrs: fix crash in parse repr options and missing delete call

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:1d93ebb1cad42c38119ec74ab5587d08c29825f2

commit 1d93ebb1cad42c38119ec74ab5587d08c29825f2
Author: Philip Herron 
Date:   Fri Mar 28 18:06:14 2025 +

gccrs: fix crash in parse repr options and missing delete call

Fixes Rust-GCC#3606

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.cc 
(TypeCheckBase::parse_repr_options):
check for null and empty and add missing delete call

gcc/testsuite/ChangeLog:

* rust/compile/issue-3606.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-base.cc | 20 ++--
 gcc/testsuite/rust/compile/issue-3606.rs   |  6 ++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index f60b540cd8c1..378ef02eda12 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -321,8 +321,22 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
  AST::AttrInputMetaItemContainer *meta_items
= option.parse_to_meta_item ();
 
- const std::string inline_option
-   = meta_items->get_items ().at (0)->as_string ();
+ if (meta_items == nullptr)
+   {
+ rust_error_at (attr.get_locus (), "malformed %qs attribute",
+"repr");
+ continue;
+   }
+
+ auto &items = meta_items->get_items ();
+ if (items.size () == 0)
+   {
+ // nothing to do with this its empty
+ delete meta_items;
+ continue;
+   }
+
+ const std::string inline_option = items.at (0)->as_string ();
 
  // TODO: it would probably be better to make the MetaItems more aware
  // of constructs with nesting like #[repr(packed(2))] rather than
@@ -359,6 +373,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
  else if (is_align)
repr.align = value;
 
+ delete meta_items;
+
  // Multiple repr options must be specified with e.g. #[repr(C,
  // packed(2))].
  break;
diff --git a/gcc/testsuite/rust/compile/issue-3606.rs 
b/gcc/testsuite/rust/compile/issue-3606.rs
new file mode 100644
index ..73b0bd6743bc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3606.rs
@@ -0,0 +1,6 @@
+// { dg-options "-w" }
+#[repr()]
+pub struct Coord {
+x: u32,
+y: u32,
+}


[gcc r15-9166] APX: Emit nf variant for rotl splitter with mask [PR 119539]

2025-04-02 Thread Hongyu Wang via Gcc-cvs
https://gcc.gnu.org/g:2488843477b3dcfeef76f8512ff6d9e8f3b58dca

commit r15-9166-g2488843477b3dcfeef76f8512ff6d9e8f3b58dca
Author: Hongyu Wang 
Date:   Mon Mar 31 16:39:23 2025 +0800

APX: Emit nf variant for rotl splitter with mask [PR 119539]

For spiltter after *3_mask it now splits the pattern
to *3_mask with flag reg clobber, and it doesn't
generate nf variant of rotate. Directly emit nf pattern when
TARGET_APX_NF enabled in these define_insn_and_split.

gcc/ChangeLog:

PR target/119539
* config/i386/i386.md (*3_mask): Emit NF variant of
rotate when APX_NF enabled, and use force_lowpart_subreg.
(*3_mask_1): Likewise.

gcc/testsuite/ChangeLog:

PR target/119539
* gcc.target/i386/apx-nf-pr119539.c: New test.

Diff:
---
 gcc/config/i386/i386.md | 22 +++---
 gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c |  6 ++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f7f790d2aeb4..d6b2f2959b23 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -18153,8 +18153,15 @@
   (match_dup 2)))
   (clobber (reg:CC FLAGS_REG))])]
 {
-  operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
-  operands[2] = gen_lowpart (QImode, operands[2]);
+  operands[2] = force_lowpart_subreg (QImode, operands[2],
+ GET_MODE (operands[2]));
+  if (TARGET_APX_NF)
+{
+  emit_move_insn (operands[0],
+ gen_rtx_ (mode, operands[1],
+ operands[2]));
+  DONE;
+}
 })
 
 (define_split
@@ -18192,7 +18199,16 @@
  [(set (match_dup 0)
   (any_rotate:SWI (match_dup 1)
   (match_dup 2)))
-  (clobber (reg:CC FLAGS_REG))])])
+  (clobber (reg:CC FLAGS_REG))])]
+{
+  if (TARGET_APX_NF)
+{
+  emit_move_insn (operands[0],
+ gen_rtx_ (mode, operands[1],
+ operands[2]));
+  DONE;
+}
+})
 
 (define_split
   [(set (match_operand:SWI 0 "register_operand")
diff --git a/gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c 
b/gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c
new file mode 100644
index ..5dfec55ed764
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/apx-nf-pr119539.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapx-features=nf -march=x86-64 -O2" } */
+/* { dg-final { scan-assembler-times "\{nf\} rol" 2 } } */
+
+long int f1 (int x) { return ~(1ULL << (x & 0x3f)); }
+long int f2 (char x) { return ~(1ULL << (x & 0x3f)); }


[gcc r15-9165] Doc: Clarify use of access attribute [PR101440]

2025-04-02 Thread Sandra Loosemore via Gcc-cvs
https://gcc.gnu.org/g:4590a31f81ae18e0d887c1a56f510d22754f31ed

commit r15-9165-g4590a31f81ae18e0d887c1a56f510d22754f31ed
Author: Sandra Loosemore 
Date:   Thu Apr 3 02:40:59 2025 +

Doc: Clarify use of access attribute [PR101440]

This issue was specifically about a confusing mention of the "second
and third arguments to the memcpy function" when only the second one
is a pointer affected by the attribute, but reading through the entire
discussion I found other things confusing as well; e.g. in some cases
it wasn't clear whether the "arguments" were the arguments to the
attribute or the function, or exactly what a "positional argument"
was.  I've tried to rewrite that part to straighten it out, as well as
some light copy-editing throughout.

gcc/ChangeLog
PR c/101440
* doc/extend.texi (Common Function Attributes): Clean up some
confusing language in the description of the "access" attribute.

Diff:
---
 gcc/doc/extend.texi | 41 ++---
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index d76d333576f9..4302df76c7fa 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1728,23 +1728,24 @@ write-only accesses to objects that are never read 
from.  Such accesses
 may be diagnosed by warnings such as @option{-Wstringop-overflow},
 @option{-Wuninitialized}, @option{-Wunused}, and others.
 
-The @code{access} attribute specifies that a function to whose by-reference
-arguments the attribute applies accesses the referenced object according to
-@var{access-mode}.  The @var{access-mode} argument is required and must be
-one of four names: @code{read_only}, @code{read_write}, @code{write_only},
-or @code{none}.  The remaining two are positional arguments.
-
-The required @var{ref-index} positional argument  denotes a function
-argument of pointer (or in C++, reference) type that is subject to
-the access.  The same pointer argument can be referenced by at most one
-distinct @code{access} attribute.
-
-The optional @var{size-index} positional argument denotes a function
+The @code{access} attribute specifies that a pointer or reference argument
+to the function is accessed according to @var{access-mode}, which must be
+one of @code{read_only}, @code{read_write}, @code{write_only},
+or @code{none}.  The semantics of these modes are described below.
+
+The argument the attribute applies to is identifed by @var{ref-index}, which
+is an integer constant representing its position in the argument list.
+Argument numbering starts from 1.  You can specify multiple @code{access}
+attributes to describe the access modes of different arguments, but multiple
+@code{access} attributes applying to the same argument are not permitted.
+
+The optional @var{size-index} denotes the position of a function
 argument of integer type that specifies the maximum size of the access.
 The size is the number of elements of the type referenced by @var{ref-index},
 or the number of bytes when the pointer type is @code{void*}.  When no
 @var{size-index} argument is specified, the pointer argument must be either
-null or point to a space that is suitably aligned and large for at least one
+null or point to a space that is suitably aligned and large enough
+for at least one
 object of the referenced type (this implies that a past-the-end pointer is
 not a valid argument).  The actual size of the access may be less but it
 must not be more.
@@ -1756,7 +1757,7 @@ is zero, the referenced object must be initialized.  The 
mode implies
 a stronger guarantee than the @code{const} qualifier which, when cast away
 from a pointer, does not prevent the pointed-to object from being modified.
 Examples of the use of the @code{read_only} access mode is the argument to
-the @code{puts} function, or the second and third arguments to
+the @code{puts} function, or the second argument to
 the @code{memcpy} function.
 
 @smallexample
@@ -1796,12 +1797,13 @@ __attribute__ ((access (write_only, 1, 2), access 
(read_write, 3)))
 int fgets (char*, int, FILE*);
 @end smallexample
 
-The access mode @code{none} specifies that the pointer to which it applies
+The access mode @code{none} specifies that the pointer argument
+to which it applies
 is not used to access the referenced object at all.  Unless the pointer is
-null the pointed-to object must exist and have at least the size as denoted
+null, the pointed-to object must exist and have at least the size as denoted
 by the @var{size-index} argument.  When the optional @var{size-index}
-argument is omitted for an argument of @code{void*} type the actual pointer
-agument is ignored.  The referenced object need not be initialized.
+argument is omitted for an argument of @code{void*} type, the actual pointer
+argument is ignored.  The referenced object need not be initialized.
 The mode is intended to be used as a means to help validate 

[gcc r13-9488] libstdc++: Fix -Warray-bounds warning in std::vector [PR110498]

2025-04-02 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:a5f7850221f935b97980e2a52b1aaeb944d7d1cf

commit r13-9488-ga5f7850221f935b97980e2a52b1aaeb944d7d1cf
Author: Jonathan Wakely 
Date:   Fri Mar 28 15:41:41 2025 +

libstdc++: Fix -Warray-bounds warning in std::vector [PR110498]

In this case, we need to tell the compiler that the current size is not
larger than the new size so that all the existing elements can be copied
to the new storage. This avoids bogus warnings about overflowing the new
storage when the compiler can't tell that that cannot happen.

We might as well also hoist the loads of begin() and end() before the
allocation too. All callers will have loaded at least begin() before
calling _M_reallocate.

libstdc++-v3/ChangeLog:

PR libstdc++/110498
* include/bits/vector.tcc (vector::_M_reallocate):
Hoist loads of begin() and end() before allocation and use them
to state an unreachable condition.
* testsuite/23_containers/vector/bool/capacity/110498.cc: New
test.

Reviewed-by: Tomasz KamiƄski 

(cherry picked from commit aa3aaf2bfb8fcc17076993df4297597b68bc5f60)

Diff:
---
 libstdc++-v3/include/bits/vector.tcc   |  5 -
 .../23_containers/vector/bool/capacity/110498.cc   | 18 ++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index 16ccfc7c02ea..58269cefeddf 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -848,9 +848,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 vector::
 _M_reallocate(size_type __n)
 {
+  const iterator __begin = begin(), __end = end();
+  if (size_type(__end - __begin) > __n)
+   __builtin_unreachable();
   _Bit_pointer __q = this->_M_allocate(__n);
   iterator __start(std::__addressof(*__q), 0);
-  iterator __finish(_M_copy_aligned(begin(), end(), __start));
+  iterator __finish(_M_copy_aligned(__begin, __end, __start));
   this->_M_deallocate();
   this->_M_impl._M_start = __start;
   this->_M_impl._M_finish = __finish;
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc
new file mode 100644
index ..d2d09e10d19a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc
@@ -0,0 +1,18 @@
+// { dg-options "-O3 -Werror=array-bounds" }
+// { dg-do compile }
+
+// Bug libstdc++/110498
+// Spurious warnings stringop-overflow and array-bounds copying data as bytes
+// into vector::reserve
+
+#include 
+
+void f(std::vector& v)
+{
+  // Warning emitted when set to any number in the range [1,64].
+  const std::size_t reserve_size = 30;
+
+  v.reserve(reserve_size);
+  v.push_back(0);
+}
+


[gcc r13-9485] libstdc++: Avoid bogus -Walloc-size-larger-than warning in test [PR116212]

2025-04-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:30a0a942007ac01601c6493b558b747d6a5b6371

commit r13-9485-g30a0a942007ac01601c6493b558b747d6a5b6371
Author: Jonathan Wakely 
Date:   Tue Apr 1 11:02:43 2025 +0100

libstdc++: Avoid bogus -Walloc-size-larger-than warning in test [PR116212]

The compiler can't tell that the vector size fits in int, so it thinks
it might overflow to a negative value, which would then be a huge
positive size_t.  In reality, the vector size never exceeds five.

There's no warning on trunk, so just change the local variable to use
type unsigned so that we get rid of the warning on the branches.

libstdc++-v3/ChangeLog:

PR libstdc++/116212
* 
testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc:
Use unsigned for vector size.

Diff:
---
 .../20_util/specialized_algorithms/uninitialized_move/constrained.cc| 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
index 23dcefdd3dfa..a4343ae8f5bb 100644
--- 
a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
+++ 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
@@ -51,7 +51,7 @@ test01(std::vector ix)
 {
   ix = saved_ix;
 
-  int size = ix.size();
+  unsigned size = ix.size();
   auto buffer = std::unique_ptr(new char[sizeof(T)*size]);
   std::span rx((T *)buffer.get(), size);


[gcc r13-9484] libstdc++: Add ranges::range_common_reference_t for C++20 (LWG 3860)

2025-04-02 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:bcfc60d64d6362e5c31a8a9f11296ab65c5ae3ab

commit r13-9484-gbcfc60d64d6362e5c31a8a9f11296ab65c5ae3ab
Author: Jonathan Wakely 
Date:   Wed Jun 12 15:02:14 2024 +0100

libstdc++: Add ranges::range_common_reference_t for C++20 (LWG 3860)

LWG 3860 added this alias template. Both libc++ and MSVC treat this as a
DR for C++20, so this change does so too.

libstdc++-v3/ChangeLog:

* include/bits/ranges_base.h (range_common_reference_t): New
alias template, as per LWG 3860.
* testsuite/std/ranges/range.cc: Check it.

(cherry picked from commit 92b554a8412624a0aa3ca9b502976ebec7eff34e)

Diff:
---
 libstdc++-v3/include/bits/ranges_base.h| 6 ++
 libstdc++-v3/testsuite/std/ranges/range.cc | 6 ++
 2 files changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/bits/ranges_base.h 
b/libstdc++-v3/include/bits/ranges_base.h
index 698dac7b7c1f..14237d2a3162 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -539,6 +539,12 @@ namespace ranges
 using range_rvalue_reference_t
   = iter_rvalue_reference_t>;
 
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3860. range_common_reference_t is missing
+  template
+using range_common_reference_t
+  = iter_common_reference_t>;
+
   /// [range.sized] The sized_range concept.
   template
 concept sized_range = range<_Tp>
diff --git a/libstdc++-v3/testsuite/std/ranges/range.cc 
b/libstdc++-v3/testsuite/std/ranges/range.cc
index f721ec38718f..76a8b8d38499 100644
--- a/libstdc++-v3/testsuite/std/ranges/range.cc
+++ b/libstdc++-v3/testsuite/std/ranges/range.cc
@@ -84,3 +84,9 @@ static_assert( 
same_as,
   char&&> );
 static_assert( same_as,
  WritableObject> );
+
+// LWG 3860. range_common_reference_t is missing
+static_assert( same_as,
+  char&> );
+static_assert( same_as,
+  char&> );


[gcc r15-9153] c: Fix ICEs with -fsanitize=pointer-{subtract, compare} [PR119582]

2025-04-02 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:29bc904cb827615ed9f36bc3742ccc4ac77515ec

commit r15-9153-g29bc904cb827615ed9f36bc3742ccc4ac77515ec
Author: Jakub Jelinek 
Date:   Wed Apr 2 19:28:20 2025 +0200

c: Fix ICEs with -fsanitize=pointer-{subtract,compare} [PR119582]

The following testcase ICEs because c_fully_fold isn't performed on the
arguments of __sanitizer_ptr_{sub,cmp} builtins and so e.g.
C_MAYBE_CONST_EXPR can leak into the gimplifier where it ICEs.

2025-04-02  Jakub Jelinek  

PR c/119582
* c-typeck.cc (pointer_diff, build_binary_op): Call c_fully_fold on
__sanitizer_ptr_sub or __sanitizer_ptr_cmp arguments.

* gcc.dg/asan/pr119582.c: New test.

Diff:
---
 gcc/c/c-typeck.cc|  8 
 gcc/testsuite/gcc.dg/asan/pr119582.c | 23 +++
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index aaf8e54416a2..19e79b554dca 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -4824,8 +4824,8 @@ pointer_diff (location_t loc, tree op0, tree op1, tree 
*instrument_expr)
   if (current_function_decl != NULL_TREE
   && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
 {
-  op0 = save_expr (op0);
-  op1 = save_expr (op1);
+  op0 = save_expr (c_fully_fold (op0, false, NULL));
+  op1 = save_expr (c_fully_fold (op1, false, NULL));
 
   tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT);
   *instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1);
@@ -14455,8 +14455,8 @@ build_binary_op (location_t location, enum tree_code 
code,
  && current_function_decl != NULL_TREE
  && sanitize_flags_p (SANITIZE_POINTER_COMPARE))
{
- op0 = save_expr (op0);
- op1 = save_expr (op1);
+ op0 = save_expr (c_fully_fold (op0, false, NULL));
+ op1 = save_expr (c_fully_fold (op1, false, NULL));
 
  tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE);
  instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1);
diff --git a/gcc/testsuite/gcc.dg/asan/pr119582.c 
b/gcc/testsuite/gcc.dg/asan/pr119582.c
new file mode 100644
index ..f33cb51adb2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr119582.c
@@ -0,0 +1,23 @@
+/* PR c/119582 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fsanitize=address,pointer-subtract,pointer-compare" } */
+
+const char v;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+char a;
+const ptrdiff_t p = &a + 1 - &a;
+const int q = (&a + 1) != &a;
+
+ptrdiff_t
+foo (void)
+{
+  char b;
+  return &b + (v != '\n') - &b;
+}
+
+int
+bar (void)
+{
+  char b;
+  return (&b + (v != '\n')) != &b;
+}


[gcc r15-9159] xfail __tcf_ZL1b assembler check on hppa*-*-hpux* in g++.dg/modules/pr98893_b.C

2025-04-02 Thread John David Anglin via Gcc-cvs
https://gcc.gnu.org/g:3b00f8b56c1b92356da81c0d80ab40da2075d536

commit r15-9159-g3b00f8b56c1b92356da81c0d80ab40da2075d536
Author: John David Anglin 
Date:   Wed Apr 2 15:06:38 2025 -0400

xfail __tcf_ZL1b assembler check on hppa*-*-hpux* in 
g++.dg/modules/pr98893_b.C

2025-04-02  John David Anglin  

gcc/testsuite/ChangeLog:

* g++.dg/modules/pr98893_b.C: xfail __tcf_ZL1b
assembler check on hppa*-*-hpux*.

Diff:
---
 gcc/testsuite/g++.dg/modules/pr98893_b.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/modules/pr98893_b.C 
b/gcc/testsuite/g++.dg/modules/pr98893_b.C
index 9065589bdfbf..692eafb0afdc 100644
--- a/gcc/testsuite/g++.dg/modules/pr98893_b.C
+++ b/gcc/testsuite/g++.dg/modules/pr98893_b.C
@@ -7,4 +7,4 @@ int main() {
 }
 
 // { dg-final { scan-assembler {__tcf_ZZ3foovE1a:} } }
-// { dg-final { scan-assembler {__tcf_ZL1b:} } }
+// { dg-final { scan-assembler {__tcf_ZL1b:} { xfail hppa*-*-hpux* } } }


[gcc r15-9155] Doc: #pragma pack documentation cleanup [PR114957] [PR78008] [PR60972]

2025-04-02 Thread Sandra Loosemore via Gcc-cvs
https://gcc.gnu.org/g:a2e03736fc932ef613ad01a9499126cbaa538bf8

commit r15-9155-ga2e03736fc932ef613ad01a9499126cbaa538bf8
Author: Sandra Loosemore 
Date:   Wed Apr 2 18:20:35 2025 +

Doc: #pragma pack documentation cleanup [PR114957] [PR78008] [PR60972]

This patch addresses a number of issues with the documentation of

- None of the things in this section had @cindex entries [PR114957].

- The document formatting didn't match that of other #pragma
documentation sections.

- The effect of #pragma pack(0) wasn't documented [PR78008].

- There's a long-standing bug [PR60972] reporting that #pragma pack
and the __attribute__(packed) don't get along well.  It seems worthwhile
to warn users about that since elsewhere pragmas are cross-referenced
with related or equivalent attributes.

gcc/ChangeLog
PR c/114957
PR c/78008
PR c++/60972
* doc/extend.texi (Structure-Layout Pragmas):  Add @cindex
entries and reformat the pragma descriptions to match the markup
used for other pragmas.  Document what #pragma pack(0) does.
Add cross-references to similar attributes.

Diff:
---
 gcc/doc/extend.texi | 87 +++--
 1 file changed, 58 insertions(+), 29 deletions(-)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 109c7d26ea28..d76d333576f9 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -9972,50 +9972,79 @@ always the C-language name.
 @node Structure-Layout Pragmas
 @subsection Structure-Layout Pragmas
 
-For compatibility with Microsoft Windows compilers, GCC supports a
-set of @code{#pragma} directives that change the maximum alignment of
+@cindex pragma, pack
+@cindex pack pragma
+For compatibility with Microsoft Windows compilers, GCC supports a set
+of @code{#pragma pack} directives that change the maximum alignment of
 members of structures (other than zero-width bit-fields), unions, and
-classes subsequently defined. The @var{n} value below always is required
-to be a small power of two and specifies the new alignment in bytes.
+classes subsequently defined. The @var{n} value below specifies the
+new alignment in bytes and may have the value 1, 2, 4, 8, and 16.  A
+value of 0 is also permitted and indicates the default alignment (as if
+no @code{#pragma pack} were in effect) should be used.
 
-@enumerate
-@item @code{#pragma pack(@var{n})} simply sets the new alignment.
-@item @code{#pragma pack()} sets the alignment to the one that was in
+@table @code
+@item #pragma pack(@var{n})
+Sets the new alignment according to @var{n}.
+
+@item #pragma pack()
+Sets the alignment to the one that was in
 effect when compilation started (see also command-line option
-@option{-fpack-struct[=@var{n}]} @pxref{Code Gen Options}).
-@item @code{#pragma pack(push[,@var{n}])} pushes the current alignment
+@option{-fpack-struct[=@var{n}]}.   @xref{Code Gen Options}).
+
+@item #pragma pack(push[,@var{n}])
+Pushes the current alignment
 setting on an internal stack and then optionally sets the new alignment.
-@item @code{#pragma pack(pop)} restores the alignment setting to the one
+
+@item #pragma pack(pop)
+Restores the alignment setting to the one
 saved at the top of the internal stack (and removes that stack entry).
 Note that @code{#pragma pack([@var{n}])} does not influence this internal
 stack; thus it is possible to have @code{#pragma pack(push)} followed by
-multiple @code{#pragma pack(@var{n})} instances and finalized by a single
-@code{#pragma pack(pop)}.
-@end enumerate
+multiple @code{#pragma pack(@var{n})} instances, with the original state
+restored by a single @code{#pragma pack(pop)}.
+
+@end table
+
+You can also use the @code{packed} type attribute (@pxref{Common Type
+Attributes}) to pack a structure.  However, the @code{packed}
+attribute interferes with @code{#pragma pack}, and attempting to use
+them together may cause spurious warnings or unexpected behavior.
+@c FIXME: This is PR 60972.
 
+@cindex pragma, ms_struct
+@cindex ms_struct pragma
+@cindex Microsoft struct layout
 Some targets, e.g.@: x86 and PowerPC, support the @code{#pragma ms_struct}
-directive which lays out structures and unions subsequently defined as the
-documented @code{__attribute__ ((ms_struct))}.
+directive, which causes subsequent structure and union declarations to
+be laid out in the same way as
+@code{__attribute__ ((ms_struct))}; @pxref{x86 Variable Attributes}.
 
-@enumerate
-@item @code{#pragma ms_struct on} turns on the Microsoft layout.
-@item @code{#pragma ms_struct off} turns off the Microsoft layout.
-@item @code{#pragma ms_struct reset} goes back to the default layout.
-@end enumerate
+@table @code
+@item #pragma ms_struct on
+Turns on the Microsoft layout.
+@item #pragma ms_struct off
+Turns off the Microsoft layout.
+@item #pragma ms_struct reset
+Goes back to the default layout.
+@end table
 
+@cindex

[gcc/devel/rust/master] Evaluate the enum's discriminant in a const context

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:b8ef598308e7bd08fb40651bf4c17490ccbb855f

commit b8ef598308e7bd08fb40651bf4c17490ccbb855f
Author: Ryutaro Okada <1015ry...@gmail.com>
Date:   Sun Mar 30 09:28:41 2025 -0700

Evaluate the enum's discriminant in a const context

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc: Evaluate the enum's 
discriminant in a const context

gcc/testsuite/ChangeLog:

* rust/compile/enum_discriminant1.rs: New test.

Signed-off-by: Ryutaro Okada <1015ry...@gmail.com>

Diff:
---
 gcc/rust/backend/rust-compile-resolve-path.cc| 2 ++
 gcc/testsuite/rust/compile/enum_discriminant1.rs | 7 +++
 2 files changed, 9 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index d4901a44bead..cdea2925e59b 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -105,7 +105,9 @@ ResolvePathRef::attempt_constructor_expression_lookup (
 
   // make the ctor for the union
   HIR::Expr &discrim_expr = variant->get_discriminant ();
+  ctx->push_const_context ();
   tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+  ctx->pop_const_context ();
   tree folded_discrim_expr = fold_expr (discrim_expr_node);
   tree qualifier = folded_discrim_expr;
 
diff --git a/gcc/testsuite/rust/compile/enum_discriminant1.rs 
b/gcc/testsuite/rust/compile/enum_discriminant1.rs
new file mode 100644
index ..32092b2c2a5b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_discriminant1.rs
@@ -0,0 +1,7 @@
+enum Foo {
+Bar = 3 + 12,
+}
+
+fn test() -> Foo { // { dg-warning "function is never used" }
+return Foo::Bar;
+}
\ No newline at end of file


[gcc r15-9168] [testsuite] [riscv] xfail ssa-dom-cse-2 on riscv64

2025-04-02 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:a17c9eb64a1f3e51876f873c64459ecb9168dc77

commit r15-9168-ga17c9eb64a1f3e51876f873c64459ecb9168dc77
Author: Alexandre Oliva 
Date:   Thu Apr 3 03:06:37 2025 -0300

[testsuite] [riscv] xfail ssa-dom-cse-2 on riscv64

For the same reasons that affect alpha and other targets,
gcc.dg/tree-ssa/ssa-dom-cse-2.c fails to be optimized to the expected
return statement: the array initializer is vectorized into pairs, and
DOM cannot see through that.

Add riscv*-*-* to the list of affected lp64 platforms.  riscv32 is
not affected.


for  gcc/testsuite/ChangeLog

* gcc.dg/tree-ssa/ssa-dom-cse-2.c: XFAIL on riscv lp64.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
index 5c89e3f86980..a879d3059714 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
@@ -27,4 +27,4 @@ foo ()
but the loop reads only one element at a time, and DOM cannot resolve these.
The same happens on powerpc depending on the SIMD support available.  */
 
-/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* 
hppa*64*-*-* nvptx*-*-* mmix-knuth-mmixware } || { { { lp64 && { powerpc*-*-* 
sparc*-*-* } } || aarch64_sve } || { arm*-*-* && { ! arm_neon } } } } } } } */
+/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* 
hppa*64*-*-* nvptx*-*-* mmix-knuth-mmixware } || { { { lp64 && { powerpc*-*-* 
sparc*-*-* riscv*-*-* } } || aarch64_sve } || { arm*-*-* && { ! arm_neon } } } 
} } } } */


[gcc r15-9170] [testsuite] [riscv] limit mcpu-xiangshan-nanhu.c to rv64

2025-04-02 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:b6d3a23cb027eb48a01ee5d70c6c72ab3bcde467

commit r15-9170-gb6d3a23cb027eb48a01ee5d70c6c72ab3bcde467
Author: Alexandre Oliva 
Date:   Thu Apr 3 03:06:47 2025 -0300

[testsuite] [riscv] limit mcpu-xiangshan-nanhu.c to rv64

The testcase makes the -march option conditional on rv64, and #errors
out if the desired CPU properties are not active.  This makes the test
fail on rv32.  Arrange to skip the test on rv32 instead, moving the
rv64 conditional.


for  gcc/testsuite/ChangeLog

* gcc.target/riscv/mcpu-xiangshan-nanhu.c: Skip on non-rv64.

Diff:
---
 gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-nanhu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-nanhu.c 
b/gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-nanhu.c
index 2903c88d91c8..c2a374f54fc8 100644
--- a/gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-nanhu.c
+++ b/gcc/testsuite/gcc.target/riscv/mcpu-xiangshan-nanhu.c
@@ -1,6 +1,6 @@
-/* { dg-do compile } */
+/* { dg-do compile { target { rv64 } } } */
 /* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
-/* { dg-options "-mcpu=xiangshan-nanhu" { target { rv64 } } } */
+/* { dg-options "-mcpu=xiangshan-nanhu" } */
 /* XiangShan Nanhu => rv64imafdc_zba_zbb_zbc_zbs_zbkb_zbkc_zbkx_zknd
   _zkne_zknh_zksed_zksh_svinval_zicbom_zicboz */


[gcc r15-9172] fold-const, cobol: Add native_encode_wide_int and use it in COBOL FE [PR119242]

2025-04-02 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:1bfc026035e6bade36538077dc1dd4f9baff0bf2

commit r15-9172-g1bfc026035e6bade36538077dc1dd4f9baff0bf2
Author: Jakub Jelinek 
Date:   Thu Apr 3 08:32:09 2025 +0200

fold-const, cobol: Add native_encode_wide_int and use it in COBOL FE 
[PR119242]

As has been mentioned earlier, various parts of the COBOL FE and the library
aren't endian clean.  In the library that means that for now we have to
live with no support for big endian targets, but in the FE that means
that as well as not being able to build cross-compilers from big endian
or pdp endian hosts to little endian targets which are otherwise supported.

The following patch attempts to fix one such spot, where it wants to encode
in target byte ordering wide_int constants into 1, 2, 4, 8 or 16 bytes.

We could wide_int_to_tree and then native_encode_expr, but so that we don't
need to build the constants, the following patch exports from fold-const.cc
a helper for native_encode_int which takes type and const wide_int_ref
reference rather than an expression.

2025-04-03  Jakub Jelinek  

PR cobol/119242
gcc/
* fold-const.h (native_encode_wide_int): Declare.
* fold-const.cc (native_encode_wide_int): New function.
(native_encode_int): Use it.
gcc/cobol/
* genapi.cc (binary_initial_from_float128): Use
native_encode_wide_int.

Diff:
---
 gcc/cobol/genapi.cc | 16 +---
 gcc/fold-const.cc   | 25 +++--
 gcc/fold-const.h|  2 ++
 3 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index 4d958cfc0d4b..a0da6476e2a8 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -15219,25 +15219,19 @@ binary_initial_from_float128(cbl_field_t *field, int 
rdigits,
   FIXED_WIDE_INT(128) i
 = FIXED_WIDE_INT(128)::from (real_to_integer (&value, &fail, 128), SIGNED);
 
-  /* ???  Use native_encode_* below.  */
   retval = (char *)xmalloc(field->data.capacity);
   switch(field->data.capacity)
 {
+  tree type;
 case 1:
-  *(signed char *)retval = (signed char)i.slow ();
-  break;
 case 2:
-  *(signed short *)retval = (signed short)i.slow ();
-  break;
 case 4:
-  *(signed int *)retval = (signed int)i.slow ();
-  break;
 case 8:
-  *(signed long *)retval = (signed long)i.slow ();
-  break;
 case 16:
-  *(unsigned long *)retval = (unsigned long)i.ulow ();
-  *((signed long *)retval + 1) = (signed long)i.shigh ();
+  type = build_nonstandard_integer_type (field->data.capacity
+* BITS_PER_UNIT, 0);
+  native_encode_wide_int (type, i, (unsigned char *)retval,
+ field->data.capacity);
   break;
 default:
   fprintf(stderr,
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index a4fb0147a0b1..3e20538de9fd 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -7465,15 +7465,16 @@ fold_plusminus_mult_expr (location_t loc, enum 
tree_code code, tree type,
   return NULL_TREE;
 }
 
-/* Subroutine of native_encode_expr.  Encode the INTEGER_CST
-   specified by EXPR into the buffer PTR of length LEN bytes.
+
+/* Subroutine of native_encode_int.  Encode the integer VAL with type TYPE
+   into the buffer PTR of length LEN bytes.
Return the number of bytes placed in the buffer, or zero
upon failure.  */
 
-static int
-native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
+int
+native_encode_wide_int (tree type, const wide_int_ref &val,
+   unsigned char *ptr, int len, int off)
 {
-  tree type = TREE_TYPE (expr);
   int total_bytes;
   if (TREE_CODE (type) == BITINT_TYPE)
 {
@@ -7516,7 +7517,7 @@ native_encode_int (const_tree expr, unsigned char *ptr, 
int len, int off)
   int bitpos = byte * BITS_PER_UNIT;
   /* Extend EXPR according to TYPE_SIGN if the precision isn't a whole
 number of bytes.  */
-  value = wi::extract_uhwi (wi::to_widest (expr), bitpos, BITS_PER_UNIT);
+  value = wi::extract_uhwi (val, bitpos, BITS_PER_UNIT);
 
   if (total_bytes > UNITS_PER_WORD)
{
@@ -7537,6 +7538,18 @@ native_encode_int (const_tree expr, unsigned char *ptr, 
int len, int off)
   return MIN (len, total_bytes - off);
 }
 
+/* Subroutine of native_encode_expr.  Encode the INTEGER_CST
+   specified by EXPR into the buffer PTR of length LEN bytes.
+   Return the number of bytes placed in the buffer, or zero
+   upon failure.  */
+
+static int
+native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
+{
+  return native_encode_wide_int (TREE_TYPE (expr), wi::to_widest (expr),
+ptr, len, off);
+}
+
 
 /* Subroutine of native_encode_expr.  Encode the FIXED_CST
specified by EXPR into the buffer PTR of length LEN bytes.
diff --git a/gcc/fold-const.h b/

[gcc r15-9173] c-family: Regenerate c.opt.urls

2025-04-02 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:047c200ffcfd301776178d5f6cd6d5108bf965bf

commit r15-9173-g047c200ffcfd301776178d5f6cd6d5108bf965bf
Author: Jakub Jelinek 
Date:   Thu Apr 3 08:46:03 2025 +0200

c-family: Regenerate c.opt.urls

On Sun, Mar 30, 2025 at 02:48:43PM +0200, Martin Uecker wrote:
> The warning -Wzero-as-null-pointer-constant is now not only supported
> in C++ but also in C.  Change the documentation accordingly.

This change didn't include make regenerate-opt-urls changes, because
moving option documentation to different section can affect the *.urls
files.

2025-04-03  Jakub Jelinek  

* c.opt.urls: Regenerate.

Diff:
---
 gcc/c-family/c.opt.urls | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index dcd81dc28d5f..802729670b08 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -976,7 +976,7 @@ Wxor-used-as-pow
 UrlSuffix(gcc/Warning-Options.html#index-Wno-xor-used-as-pow)
 
 Wzero-as-null-pointer-constant
-UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-zero-as-null-pointer-constant)
+UrlSuffix(gcc/Warning-Options.html#index-Wno-zero-as-null-pointer-constant)
 
 Wzero-length-bounds
 UrlSuffix(gcc/Warning-Options.html#index-Wzero-length-bounds)


[gcc r15-9148] switch-3.c: Fix llp64 warnings

2025-04-02 Thread Jonathan Yong via Gcc-cvs
https://gcc.gnu.org/g:e7912d4a81cf34e05c7ded70910069b691a8bb15

commit r15-9148-ge7912d4a81cf34e05c7ded70910069b691a8bb15
Author: Jonathan Yong <10wa...@gmail.com>
Date:   Wed Apr 2 11:18:21 2025 +

switch-3.c: Fix llp64 warnings

mtrr_ioctl() uses long and casts it to a pointer. Fix warnings
for llp64 platforms.

Signed-off-by: Jonathan Yong <10wa...@gmail.com>

gcc/testsuite/ChangeLog:

* gcc.dg/analyzer/torture/switch-3.c: Fix llp64 warnings.

Diff:
---
 gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c 
b/gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c
index 57b8acdb2929..b40be664d389 100644
--- a/gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/switch-3.c
@@ -68,7 +68,7 @@ extern void check_init_u32 (__u32 v);
 /* Adapted/reduced from arch/x86/kernel/cpu/mtrr/if.c: mtrr_ioctl,
which is GPL-2.0  */
 
-long mtrr_ioctl(unsigned int cmd, unsigned long __arg) {
+long mtrr_ioctl(unsigned int cmd, __UINTPTR_TYPE__ __arg) {
   int err = 0;
   struct mtrr_sentry sentry;
   struct mtrr_gentry gentry;


[gcc r14-11520] tree-optimization/119145 - avoid stray .MASK_CALL after vectorization

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:534a7895e969793285c77a42aca62d426cd56c1e

commit r14-11520-g534a7895e969793285c77a42aca62d426cd56c1e
Author: Richard Biener 
Date:   Fri Mar 7 10:15:20 2025 +0100

tree-optimization/119145 - avoid stray .MASK_CALL after vectorization

When we BB vectorize an if-converted loop body we make sure to not
leave around .MASK_LOAD or .MASK_STORE created by if-conversion but
we failed to check for .MASK_CALL.

PR tree-optimization/119145
* tree-vectorizer.cc (try_vectorize_loop_1): Avoid BB
vectorizing an if-converted loop body when there's a .MASK_CALL
in the loop body.

* gcc.dg/vect/pr119145.c: New testcase.

(cherry picked from commit 7950d4cceb9fc7559b1343c95fc651cefbe287a0)

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr119145.c | 35 +++
 gcc/tree-vectorizer.cc   |  4 +++-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr119145.c 
b/gcc/testsuite/gcc.dg/vect/pr119145.c
new file mode 100644
index ..55a84a603c49
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119145.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+
+typedef short Quantum;
+Quantum ComplexImages_Bi_0, ComplexImages_Ai_0, ComplexImages_Ai_1;
+long ComplexImages_x;
+__attribute__((__simd__)) double atan2(double, double);
+typedef enum { MagickFalse } MagickBooleanType;
+
+struct {
+MagickBooleanType matte;
+} *ComplexImages_images;
+
+typedef struct {
+Quantum blue, opacity;
+} PixelPacket;
+
+typedef enum { MagnitudePhaseComplexOperator } ComplexOperator;
+PixelPacket ComplexImages_Ar, ComplexImages_Br;
+PixelPacket *ComplexImages_Ci;
+ComplexOperator ComplexImages_op;
+
+void ComplexImages()
+{
+  for (; ComplexImages_x; ComplexImages_x++)
+switch (ComplexImages_op)
+  {
+  case MagnitudePhaseComplexOperator:
+if (ComplexImages_images->matte)
+ ComplexImages_Ci->opacity
+   = atan2(ComplexImages_Ai_1, ComplexImages_Ar.opacity);
+   ComplexImages_Ci->blue
+ = 1.0 / (ComplexImages_Ai_0 * ComplexImages_Br.blue
+  + ComplexImages_Ar.blue * ComplexImages_Bi_0);
+  }
+}
diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc
index 6062355b781d..35ee08796d4c 100644
--- a/gcc/tree-vectorizer.cc
+++ b/gcc/tree-vectorizer.cc
@@ -1103,7 +1103,9 @@ try_vectorize_loop_1 (hash_table 
*&simduid_to_vf_htab,
  if (call && gimple_call_internal_p (call))
{
  internal_fn ifn = gimple_call_internal_fn (call);
- if (ifn == IFN_MASK_LOAD || ifn == IFN_MASK_STORE
+ if (ifn == IFN_MASK_LOAD
+ || ifn == IFN_MASK_STORE
+ || ifn == IFN_MASK_CALL
  /* Don't keep the if-converted parts when the ifn with
 specifc type is not supported by the backend.  */
  || (direct_internal_fn_p (ifn)


[gcc r14-11519] middle-end/119119 - re-gimplification of empty CTOR assignments

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:2f87983131eab6bdad7da4c6ef9ce026966966a5

commit r14-11519-g2f87983131eab6bdad7da4c6ef9ce026966966a5
Author: Richard Biener 
Date:   Thu Mar 6 09:08:07 2025 +0100

middle-end/119119 - re-gimplification of empty CTOR assignments

The following testcase runs into a re-gimplification issue during
inlining when processing

  MEM[(struct e *)this_2(D)].a = {};

where re-gimplification does not handle assignments in the same
way than the gimplifier but instead relies on rhs_predicate_for
and gimplifying the RHS standalone.  This fails to handle
special-casing of CTORs.  The is_gimple_mem_rhs_or_call predicate
already handles clobbers but not empty CTORs so we end up in
the fallback code trying to force the CTOR into a separate stmt
using a temporary - but as we have a non-copyable type here that ICEs.

The following generalizes empty CTORs in is_gimple_mem_rhs_or_call
since those need no additional re-gimplification.

PR middle-end/119119
* gimplify.cc (is_gimple_mem_rhs_or_call): All empty CTORs
are OK when not a register type.

* g++.dg/torture/pr11911.C: New testcase.

(cherry picked from commit 3bd61c1dfaa2d7153eb4be82f423533ea937d0f9)

Diff:
---
 gcc/gimplify.cc|  2 +-
 gcc/testsuite/g++.dg/torture/pr11911.C | 21 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index b85c6ffbe9b8..5ee5f8c08e8e 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -575,7 +575,7 @@ is_gimple_mem_rhs_or_call (tree t)
   else
 return (is_gimple_val (t)
|| is_gimple_lvalue (t)
-   || TREE_CLOBBER_P (t)
+   || (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0)
|| TREE_CODE (t) == CALL_EXPR);
 }
 
diff --git a/gcc/testsuite/g++.dg/torture/pr11911.C 
b/gcc/testsuite/g++.dg/torture/pr11911.C
new file mode 100644
index ..7dc836ff9b53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr11911.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+
+struct b {
+  int a;
+};
+struct c {
+  b d{};
+  c() = default;
+  c(c &) = delete;
+};
+struct e {
+  c a{};
+  e() {}
+};
+inline e f() { return {}; }
+struct g {
+  e cx;
+  g() : cx{f()} {}
+};
+void h() { g i; }


[gcc(refs/users/jmelcr/heads/omp-cp)] omp-cp: Fix redirections, callback edge deletion

2025-04-02 Thread Josef Melcr via Gcc-cvs
https://gcc.gnu.org/g:060374f2294e5df3bf1c96e2051a06b8f7051ba6

commit 060374f2294e5df3bf1c96e2051a06b8f7051ba6
Author: Josef Melcr 
Date:   Wed Apr 2 11:06:35 2025 +0200

omp-cp: Fix redirections, callback edge deletion

gcc/ChangeLog:

* attr-callback.h (callback_remove_callback_edge): Remove
function.
* cgraph.cc (cgraph_edge::set_call_stmt): Add null check.
(cgraph_node::verify_node): Change verifying logic to account
for CB edge deletion.
* ipa-cp.cc (purge_useless_callback_edges): Change deletion
function, more logging.
* ipa-fnsummary.cc (ipa_call_summary_t::duplicate): Exclude
callback edges when subtracting size and time.
* ipa-inline-analysis.cc (do_estimate_growth_1): Skip callback
edges when calculating inlining cost.
* ipa-inline-transform.cc (inline_transform): Add callback edge
redirection.
* tree-inline.cc (redirect_all_calls): Likewise.

Signed-off-by: Josef Melcr 

Diff:
---
 gcc/attr-callback.h | 31 ---
 gcc/cgraph.cc   | 32 
 gcc/ipa-cp.cc   | 10 +-
 gcc/ipa-fnsummary.cc|  3 ++-
 gcc/ipa-inline-analysis.cc  |  3 +++
 gcc/ipa-inline-transform.cc |  7 ++-
 gcc/tree-inline.cc  | 12 ++--
 7 files changed, 46 insertions(+), 52 deletions(-)

diff --git a/gcc/attr-callback.h b/gcc/attr-callback.h
index 622949c03ac3..cf22808c9b8b 100644
--- a/gcc/attr-callback.h
+++ b/gcc/attr-callback.h
@@ -288,35 +288,4 @@ callback_edge_useful_p (cgraph_edge *e)
   return true;
 }
 
-inline void
-callback_remove_callback_edge (cgraph_edge *e)
-{
-  gcc_checking_assert (e->callback);
-  cgraph_edge *parent = e->get_callback_parent_edge ();
-  tree offload_decl = parent->callee->decl;
-  if (parent->call_stmt)
-{
-  tree attr = callback_fetch_attr_by_decl (parent->call_stmt,
-  DECL_ATTRIBUTES (offload_decl),
-  e->callee->decl);
-
-  tree *p;
-  tree list = DECL_ATTRIBUTES (offload_decl);
-  for (p = &list; *p;)
-   {
- tree l = *p;
-
- if (l == attr)
-   {
- *p = TREE_CHAIN (l);
- continue;
-   }
- p = &TREE_CHAIN (l);
-   }
-
-  DECL_ATTRIBUTES (offload_decl) = list;
-}
-  cgraph_edge::remove (e);
-}
-
 #endif /* ATTR_CALLBACK_H  */
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 60a4f49014c3..a1bb366265e7 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -851,19 +851,22 @@ cgraph_edge::set_call_stmt (cgraph_edge *e, gcall 
*new_stmt,
   cgraph_edge *current, *next;
 
   current = e->first_callback_target ();
-  gcall *old_stmt = current->call_stmt;
-  for (cgraph_edge *d = current; d; d = next)
+  if (current)
{
- next = d->next_callee;
- for (; next; next = next->next_callee)
+ gcall *old_stmt = current->call_stmt;
+ for (cgraph_edge *d = current; d; d = next)
{
- /* has_callback doesn't need to checked, as their
-call statements wouldn't match */
- if (next->callback && old_stmt == next->call_stmt)
-   break;
+ next = d->next_callee;
+ for (; next; next = next->next_callee)
+   {
+ /* has_callback doesn't need to checked, as their
+call statements wouldn't match */
+ if (next->callback && old_stmt == next->call_stmt)
+   break;
+   }
+ cgraph_edge *d2 = set_call_stmt (d, new_stmt, false);
+ gcc_assert (d2 == d);
}
- cgraph_edge *d2 = set_call_stmt (d, new_stmt, false);
- gcc_assert (d2 == d);
}
 }
 
@@ -3824,6 +3827,7 @@ cgraph_node::verify_node (void)
  && !e->caller->inlined_to
  && !e->speculative
  && !e->callback
+ && !e->has_callback
  /* Optimized out calls are redirected to __builtin_unreachable.  */
  && (e->count.nonzero_p ()
  || ! e->callee->decl
@@ -4107,15 +4111,11 @@ cgraph_node::verify_node (void)
{
  nfound_edges++;
}
- else if (cbe->callback) {
-   fprintf (stderr, "sus verify %s -> %s\n",
-cbe->caller->name (), cbe->callee->name ());
- }
}
- if (ncallbacks != nfound_edges)
+ if (ncallbacks < nfound_edges)
{
  error ("callback edge %s->%s child edge count mismatch, "
-"expected %d, found %d",
+"expected at most %d, found %d",
 identifier_to_locale (e->c

[gcc/devel/omp/gcc-14] GCN: Don't emit weak undefined symbols [PR119369]

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:f82475810a3c09284e87fb99b95f64f7704078a9

commit f82475810a3c09284e87fb99b95f64f7704078a9
Author: Thomas Schwinge 
Date:   Mon Mar 31 09:55:14 2025 +0200

GCN: Don't emit weak undefined symbols [PR119369]

This resolves all instances of PR119369
"GCN: weak undefined symbols -> execution test FAIL, 
'HSA_STATUS_ERROR_VARIABLE_UNDEFINED'";
for all affected test cases, the execution test status progresses FAIL -> 
PASS.

This however also causes a small number of (expected) regressions, very 
similar
to GCC/nvptx:

[-PASS:-]{+FAIL:+} g++.dg/abi/pure-virtual1.C  -std=c++17 (test for 
excess errors)
[-PASS:-]{+FAIL:+} g++.dg/abi/pure-virtual1.C  -std=c++26 (test for 
excess errors)
[-PASS:-]{+FAIL:+} g++.dg/abi/pure-virtual1.C  -std=c++98 (test for 
excess errors)

[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++11  scan-assembler 
.weak[ \t]*_?_ZTH11derived_obj
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++11  scan-assembler 
.weak[ \t]*_?_ZTH13container_obj
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++11  scan-assembler 
.weak[ \t]*_?_ZTH8base_obj
PASS: g++.dg/cpp0x/pr84497.C  -std=c++11 (test for excess errors)
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++17  scan-assembler 
.weak[ \t]*_?_ZTH11derived_obj
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++17  scan-assembler 
.weak[ \t]*_?_ZTH13container_obj
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++17  scan-assembler 
.weak[ \t]*_?_ZTH8base_obj
PASS: g++.dg/cpp0x/pr84497.C  -std=c++17 (test for excess errors)
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++26  scan-assembler 
.weak[ \t]*_?_ZTH11derived_obj
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++26  scan-assembler 
.weak[ \t]*_?_ZTH13container_obj
[-PASS:-]{+FAIL:+} g++.dg/cpp0x/pr84497.C  -std=c++26  scan-assembler 
.weak[ \t]*_?_ZTH8base_obj
PASS: g++.dg/cpp0x/pr84497.C  -std=c++26 (test for excess errors)

[-PASS:-]{+FAIL:+} g++.dg/ext/weak2.C  -std=gnu++17  scan-assembler 
weak[^ \t]*[ \t]_?_Z3foov
PASS: g++.dg/ext/weak2.C  -std=gnu++17 (test for excess errors)
[-PASS:-]{+FAIL:+} g++.dg/ext/weak2.C  -std=gnu++26  scan-assembler 
weak[^ \t]*[ \t]_?_Z3foov
PASS: g++.dg/ext/weak2.C  -std=gnu++26 (test for excess errors)
[-PASS:-]{+FAIL:+} g++.dg/ext/weak2.C  -std=gnu++98  scan-assembler 
weak[^ \t]*[ \t]_?_Z3foov
PASS: g++.dg/ext/weak2.C  -std=gnu++98 (test for excess errors)

[-PASS:-]{+FAIL:+} gcc.dg/attr-weakref-1.c (test for excess errors)
[-FAIL:-]{+UNRESOLVED:+} gcc.dg/attr-weakref-1.c [-execution 
test-]{+compilation failed to produce executable+}

@@ -131211,25 +131211,25 @@ PASS: gcc.dg/weak/weak-1.c scan-assembler 
weak[^ \t]*[ \t]_?c
PASS: gcc.dg/weak/weak-1.c scan-assembler weak[^ \t]*[ \t]_?d
PASS: gcc.dg/weak/weak-1.c scan-assembler weak[^ \t]*[ \t]_?e
PASS: gcc.dg/weak/weak-1.c scan-assembler weak[^ \t]*[ \t]_?g
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-1.c scan-assembler weak[^ \t]*[ 
\t]_?j
PASS: gcc.dg/weak/weak-1.c scan-assembler-not weak[^ \t]*[ \t]_?i

PASS: gcc.dg/weak/weak-12.c (test for excess errors)
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-12.c scan-assembler weak[^ \t]*[ 
\t]_?foo

PASS: gcc.dg/weak/weak-15.c (test for excess errors)
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-15.c scan-assembler weak[^ \t]*[ 
\t]_?a
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-15.c scan-assembler weak[^ \t]*[ 
\t]_?c
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-15.c scan-assembler weak[^ \t]*[ 
\t]_?d
PASS: gcc.dg/weak/weak-15.c scan-assembler-not weak[^ \t]*[ \t]_?b

PASS: gcc.dg/weak/weak-16.c (test for excess errors)
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-16.c scan-assembler weak[^ \t]*[ 
\t]_?kallsyms_token_index
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-16.c scan-assembler weak[^ \t]*[ 
\t]_?kallsyms_token_table
PASS: gcc.dg/weak/weak-2.c (test for excess errors)
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-2.c scan-assembler weak[^ \t]*[ 
\t]_?ffoo1a
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-2.c scan-assembler weak[^ \t]*[ 
\t]_?ffoo1b
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-2.c scan-assembler weak[^ \t]*[ 
\t]_?ffoo1c
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-2.c scan-assembler weak[^ \t]*[ 
\t]_?ffoo1e
PASS: gcc.dg/weak/weak-2.c scan-assembler-not weak[^ \t]*[ \t]_?ffoo1d

PASS: gcc.dg/weak/weak-3.c  (test for warnings, line 58)
PASS: gcc.dg/weak/weak-3.c  (test for warnings, line 73)
PASS: gcc.dg/weak/weak-3.c (test for excess errors)
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-3.c scan-assembler weak[^ \t]*[ 
\t]_?ffoo1a
[-PASS:-]{+FAIL:+} gcc.dg/weak/weak-3.c scan-assembler weak[^ \t]*[ 
\t]_?ffoo1b
[-PASS:-]{+FAIL:+} gcc.dg/weak/we

[gcc/devel/omp/gcc-14] GCN, libstdc++: '#define _GLIBCXX_USE_WEAK_REF 0' [PR119369]

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:45fe2a8c8a2a8b9e1b30d83712ede442ef206598

commit 45fe2a8c8a2a8b9e1b30d83712ede442ef206598
Author: Thomas Schwinge 
Date:   Sun Mar 30 14:54:01 2025 +0200

GCN, libstdc++: '#define _GLIBCXX_USE_WEAK_REF 0' [PR119369]

This fixes a few hundreds of compilation/linking FAILs (similar to PR69506),
where the GCN/LLVM 'ld' reported:

ld: error: relocation R_AMDGPU_REL32_LO cannot be used against symbol 
'_ZGTtnam'; recompile with -fPIC
>>> defined in 
[...]/amdgcn-amdhsa/./libstdc++-v3/src/.libs/libstdc++.a(cow-stdexcept.o)
>>> referenced by cow-stdexcept.cc:259 
([...]/libstdc++-v3/src/c++11/cow-stdexcept.cc:259)
>>>   
cow-stdexcept.o:(_txnal_cow_string_C1_for_exceptions(void*, char const*, 
void*)) in archive [...]/amdgcn-amdhsa/./libstdc++-v3/src/.libs/libstdc++.a

ld: error: relocation R_AMDGPU_REL32_HI cannot be used against symbol 
'_ZGTtnam'; recompile with -fPIC
>>> defined in 
[...]/amdgcn-amdhsa/./libstdc++-v3/src/.libs/libstdc++.a(cow-stdexcept.o)
>>> referenced by cow-stdexcept.cc:259 
([...]/source-gcc/libstdc++-v3/src/c++11/cow-stdexcept.cc:259)
>>>   
cow-stdexcept.o:(_txnal_cow_string_C1_for_exceptions(void*, char const*, 
void*)) in archive [...]/amdgcn-amdhsa/./libstdc++-v3/src/.libs/libstdc++.a

[...]

..., which is:

$ c++filt _ZGTtnam
transaction clone for operator new[](unsigned long)

..., and similarly for other libitm symbols.

However, the affected test cases, if applicable, then run into execution 
test
FAILs, due to PR119369
"GCN: weak undefined symbols -> execution test FAIL, 
'HSA_STATUS_ERROR_VARIABLE_UNDEFINED'".

PR target/119369
libstdc++-v3/
* config/cpu/gcn/cpu_defines.h: New.
* configure.host [GCN] (cpu_defines_dir): Point to it.

(cherry picked from commit 816335960d020eac92d49bc9cd13729afd313da7)

Diff:
---
 libstdc++-v3/ChangeLog.omp|  9 +
 libstdc++-v3/config/cpu/gcn/cpu_defines.h | 55 +++
 libstdc++-v3/configure.host   |  3 ++
 3 files changed, 67 insertions(+)

diff --git a/libstdc++-v3/ChangeLog.omp b/libstdc++-v3/ChangeLog.omp
index 108b11554997..e1f89cb9fa4f 100644
--- a/libstdc++-v3/ChangeLog.omp
+++ b/libstdc++-v3/ChangeLog.omp
@@ -1,3 +1,12 @@
+2025-04-02  Thomas Schwinge  
+
+   Backported from trunk:
+   2025-04-01  Thomas Schwinge  
+
+   PR target/119369
+   * config/cpu/gcn/cpu_defines.h: New.
+   * configure.host [GCN] (cpu_defines_dir): Point to it.
+
 2025-03-19  Thomas Schwinge  
 
Backported from trunk:
diff --git a/libstdc++-v3/config/cpu/gcn/cpu_defines.h 
b/libstdc++-v3/config/cpu/gcn/cpu_defines.h
new file mode 100644
index ..028bfb0ccff1
--- /dev/null
+++ b/libstdc++-v3/config/cpu/gcn/cpu_defines.h
@@ -0,0 +1,55 @@
+// Specific definitions for GCN platforms  -*- C++ -*-
+
+// Copyright (C) 2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// .
+
+/** @file bits/cpu_defines.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{iosfwd}
+ */
+
+#ifndef _GLIBCXX_CPU_DEFINES
+#define _GLIBCXX_CPU_DEFINES 1
+
+/* GCN appears to run into issues similar to PR69506:
+
+   ld: error: relocation R_AMDGPU_REL32_LO cannot be used against symbol 
'_ZGTtnam'; recompile with -fPIC
+   >>> defined in 
[...]/amdgcn-amdhsa/./libstdc++-v3/src/.libs/libstdc++.a(cow-stdexcept.o)
+   >>> referenced by cow-stdexcept.cc:259 
([...]/libstdc++-v3/src/c++11/cow-stdexcept.cc:259)
+   >>>   
cow-stdexcept.o:(_txnal_cow_string_C1_for_exceptions(void*, char const*, 
void*)) in archive [...]/amdgcn-amdhsa/./libstdc++-v3/src/.libs/libstdc++.a
+   
+   ld: error: relocation R_AMDGPU_REL32_HI cannot be used against symbol 
'_ZGTtnam'; recompile with -fPIC
+   

[gcc r14-11515] lto/114501 - missed free-lang-data for CONSTRUCTOR index

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:ed7f67d951292a3f93e5509741b511fd9ea7da30

commit r14-11515-ged7f67d951292a3f93e5509741b511fd9ea7da30
Author: Richard Biener 
Date:   Thu Mar 6 13:48:16 2025 +0100

lto/114501 - missed free-lang-data for CONSTRUCTOR index

The following makes sure to also walk CONSTRUCTOR element indexes
which can be FIELD_DECLs, referencing otherwise unused types we
need to clean.  walk_tree only walks CONSTRUCTOR element data.

PR lto/114501
* ipa-free-lang-data.cc (find_decls_types_r): Explicitly
handle CONSTRUCTORs as walk_tree handling of those is
incomplete.

* g++.dg/pr114501_0.C: New testcase.

(cherry picked from commit fdd95e1cf29137a19baed25f8c817d320dfe63e3)

Diff:
---
 gcc/ipa-free-lang-data.cc | 14 ++
 gcc/testsuite/g++.dg/pr114501_0.C | 20 
 2 files changed, 34 insertions(+)

diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc
index b04bc5f3d89a..ff87c205b1c5 100644
--- a/gcc/ipa-free-lang-data.cc
+++ b/gcc/ipa-free-lang-data.cc
@@ -841,6 +841,20 @@ find_decls_types_r (tree *tp, int *ws, void *data)
fld_worklist_push (tem, fld);
   fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
 }
+  /* walk_tree does not visit ce->index which can be a FIELD_DECL, pulling
+ in otherwise unused structure fields so handle CTORs explicitly.  */
+  else if (TREE_CODE (t) == CONSTRUCTOR)
+{
+  unsigned HOST_WIDE_INT idx;
+  constructor_elt *ce;
+  for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++)
+   {
+ if (ce->index)
+   fld_worklist_push (ce->index, fld);
+ fld_worklist_push (ce->value, fld);
+   }
+  *ws = 0;
+}
 
   if (TREE_CODE (t) != IDENTIFIER_NODE
   && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
diff --git a/gcc/testsuite/g++.dg/pr114501_0.C 
b/gcc/testsuite/g++.dg/pr114501_0.C
new file mode 100644
index ..0439ee5f6e23
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr114501_0.C
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-require-effective-target lto }
+// { dg-options "-flto" }
+
+typedef long unsigned int size_t;
+struct basic_string_view {
+  typedef long unsigned int size_type;
+  constexpr size_type size() const { return 0; }
+};
+struct array {
+  char _M_elems[1];
+};
+inline constexpr auto make_it() {
+  constexpr basic_string_view view;
+  array arr{};
+  arr._M_elems[view.size()] = 'a';
+  return arr;
+}
+auto bar = make_it();


[gcc r14-11514] ipa/111245 - bogus modref analysis for store in call that might throw

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:d9faa7c2eb47c7fabf9dafce6d569f52d49c7030

commit r14-11514-gd9faa7c2eb47c7fabf9dafce6d569f52d49c7030
Author: Richard Biener 
Date:   Fri Feb 28 11:44:26 2025 +0100

ipa/111245 - bogus modref analysis for store in call that might throw

We currently record a kill for

  *x_4(D) = always_throws ();

because we consider the store always executing since the appropriate
check for whether the stmt could throw is guarded by
!cfun->can_throw_non_call_exceptions.

PR ipa/111245
* ipa-modref.cc (modref_access_analysis::analyze_store): Do
not guard the check of whether the stmt could throw by
cfun->can_throw_non_call_exceptions.

* g++.dg/torture/pr111245.C: New testcase.

(cherry picked from commit e6037af6d5e5a43c437257580d75bc8b35a6dcfd)

Diff:
---
 gcc/ipa-modref.cc   |  3 +--
 gcc/testsuite/g++.dg/torture/pr111245.C | 23 +++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 400a8856de2d..b38bb7cf449d 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -1747,8 +1747,7 @@ modref_access_analysis::analyze_store (gimple *stmt, 
tree, tree op, void *data)
 t->record_access_lto (t->m_summary_lto->stores, &r, a);
   if (t->m_always_executed
   && a.useful_for_kill_p ()
-  && (!cfun->can_throw_non_call_exceptions
- || !stmt_could_throw_p (cfun, stmt)))
+  && !stmt_could_throw_p (cfun, stmt))
 {
   if (dump_file)
fprintf (dump_file, "   - Recording kill\n");
diff --git a/gcc/testsuite/g++.dg/torture/pr111245.C 
b/gcc/testsuite/g++.dg/torture/pr111245.C
new file mode 100644
index ..785f4a51761d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr111245.C
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+struct Int {
+  int value;
+};
+
+__attribute__((noipa)) Int always_throws() { throw 123; }
+
+void foo(Int &x) {
+  try {
+x = always_throws();
+  } catch (...) {
+  }
+}
+
+int main()
+{
+  Int x;
+  x.value = 5;
+  foo(x);
+  if (x.value != 5)
+__builtin_abort ();
+}


[gcc r14-11516] tree-optimization/119057 - bogus double reduction detection

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:faadd1d27a85478f43c90cf780f980d0cbd37b85

commit r14-11516-gfaadd1d27a85478f43c90cf780f980d0cbd37b85
Author: Richard Biener 
Date:   Mon Mar 3 13:21:53 2025 +0100

tree-optimization/119057 - bogus double reduction detection

We are detecting a cycle as double reduction where the inner loop
cycle has extra out-of-loop uses.  This clashes at least with
assumptions from the SLP discovery code which says the cycle
isn't reachable from another SLP instance.  It also was not intended
to support this case, in fact with GCC 14 we seem to generate wrong
code here.

PR tree-optimization/119057
* tree-vect-loop.cc (check_reduction_path): Add argument
specifying whether we're analyzing the inner loop of a
double reduction.  Do not allow extra uses outside of the
double reduction cycle in this case.
(vect_is_simple_reduction): Adjust.

* gcc.dg/vect/pr119057.c: New testcase.

(cherry picked from commit 758de6263dfc7ba8701965fa468691ac23cb7eb5)

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr119057.c | 19 +++
 gcc/tree-vect-loop.cc| 12 +++-
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr119057.c 
b/gcc/testsuite/gcc.dg/vect/pr119057.c
new file mode 100644
index ..582bb8ff86c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119057.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-vrp -fno-tree-forwprop" } */
+
+int a, b, c, d;
+unsigned e;
+static void f(void)
+{
+  unsigned h;
+  for (d = 0; d < 2; d++)
+b |= e;
+  h = b;
+  c |= h;
+}
+int main()
+{
+  for (; a; a++)
+f();
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index be0359fa3d16..95f6d06820f3 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -4032,7 +4032,8 @@ needs_fold_left_reduction_p (tree type, code_helper code)
 static bool
 check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi,
  tree loop_arg, code_helper *code,
- vec > &path)
+ vec > &path,
+ bool inner_loop_of_double_reduc)
 {
   auto_bitmap visited;
   tree lookfor = PHI_RESULT (phi);
@@ -4169,7 +4170,8 @@ pop:
  break;
}
   /* Check there's only a single stmt the op is used on.  For the
-not value-changing tail and the last stmt allow out-of-loop uses.
+not value-changing tail and the last stmt allow out-of-loop uses,
+but not when this is the inner loop of a double reduction.
 ???  We could relax this and handle arbitrary live stmts by
 forcing a scalar epilogue for example.  */
   imm_use_iterator imm_iter;
@@ -4204,7 +4206,7 @@ pop:
}
}
  else if (!is_gimple_debug (op_use_stmt)
-  && (*code != ERROR_MARK
+  && ((*code != ERROR_MARK || inner_loop_of_double_reduc)
   || flow_bb_inside_loop_p (loop,
 gimple_bb (op_use_stmt
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
@@ -4226,7 +4228,7 @@ check_reduction_path (dump_user_location_t loc, loop_p 
loop, gphi *phi,
 {
   auto_vec > path;
   code_helper code_;
-  return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path)
+  return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path, false)
  && code_ == code);
 }
 
@@ -4436,7 +4438,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, 
stmt_vec_info phi_info,
   auto_vec > path;
   code_helper code;
   if (check_reduction_path (vect_location, loop, phi, latch_def, &code,
-   path))
+   path, inner_loop_of_double_reduc))
 {
   STMT_VINFO_REDUC_CODE (phi_info) = code;
   if (code == COND_EXPR && !nested_in_vect_loop)


[gcc r15-9152] OpenMP: Require target and/or targetsync init modifier [PR118965]

2025-04-02 Thread Sandra Loosemore via Gcc-cvs
https://gcc.gnu.org/g:aca8155c09001f269a20d6df438fa0e749dd5388

commit r15-9152-gaca8155c09001f269a20d6df438fa0e749dd5388
Author: Sandra Loosemore 
Date:   Mon Mar 31 22:02:35 2025 +

OpenMP: Require target and/or targetsync init modifier [PR118965]

As noted in PR 118965, the initial interop implementation overlooked
the requirement in the OpenMP spec that at least one of the "target"
and "targetsync" modifiers is required in both the interop construct
init clause and the declare variant append_args clause.

Adding the check was fairly straightforward, but it broke about a
gazillion existing test cases.  In particular, things like "init (x, y)"
which were previously accepted (and tested for being accepted) aren't
supposed to be allowed by the spec, much less things like "init (target)"
where target was previously interpreted as a variable name instead of a
modifier.  Since one of the effects of the change is that at least one
modifier is always required, I found that deleting all the code that was
trying to detect and handle the no-modifier case allowed for better
diagnostics.

gcc/c/ChangeLog
PR middle-end/118965
* c-parser.cc (c_parser_omp_clause_init_modifiers): Adjust
error message.
(c_parser_omp_clause_init): Remove code for recognizing clauses
without modifiers.  Diagnose missing target/targetsync modifier.
(c_finish_omp_declare_variant): Diagnose missing target/targetsync
modifier.

gcc/cp/ChangeLog
PR middle-end/118965
* parser.cc (c_parser_omp_clause_init_modifiers): Adjust
error message.
(cp_parser_omp_clause_init): Remove code for recognizing clauses
without modifiers.  Diagnose missing target/targetsync modifier.
(cp_finish_omp_declare_variant): Diagnose missing target/targetsync
modifier.

gcc/fortran/ChangeLog
PR middle-end/118965
* openmp.cc (gfc_parser_omp_clause_init_modifiers): Fix some
inconsistent code indentation.  Remove code for recognizing
clauses without modifiers.  Diagnose prefer_type without a
following paren.  Adjust error message for an unrecognized modifier.
Diagnose missing target/targetsync modifier.
(gfc_match_omp_init): Fix more inconsistent code indentation.

gcc/testsuite/ChangeLog
PR middle-end/118965
* c-c++-common/gomp/append-args-1.c: Add target/targetsync
modifiers so tests do what they were previously supposed to do.
Adjust expected output.
* c-c++-common/gomp/append-args-7.c: Likewise.
* c-c++-common/gomp/append-args-8.c: Likewise.
* c-c++-common/gomp/append-args-9.c: Likewise.
* c-c++-common/gomp/interop-1.c: Likewise.
* c-c++-common/gomp/interop-2.c: Likewise.
* c-c++-common/gomp/interop-3.c: Likewise.
* c-c++-common/gomp/interop-4.c: Likewise.
* c-c++-common/gomp/pr118965-1.c: New.
* c-c++-common/gomp/pr118965-2.c: New.
* g++.dg/gomp/append-args-1.C: Add target/targetsync modifiers
and adjust expected output.
* g++.dg/gomp/append-args-2.C: Likewise.
* g++.dg/gomp/append-args-6.C: Likewise.
* g++.dg/gomp/append-args-7.C: Likewise.
* g++.dg/gomp/append-args-8.C: Likewise.
* g++.dg/gomp/interop-5.C: Likewise.
* gfortran.dg/gomp/append_args-1.f90: Add target/targetsync
modifiers and adjust expected output.
* gfortran.dg/gomp/append_args-2.f90: Likewise.
* gfortran.dg/gomp/append_args-3.f90: Likewise.
* gfortran.dg/gomp/append_args-4.f90: Likewise.
* gfortran.dg/gomp/interop-1.f90: Likewise.
* gfortran.dg/gomp/interop-2.f90: Likewise.
* gfortran.dg/gomp/interop-3.f90: Likewise.
* gfortran.dg/gomp/interop-4.f90: Likewise.
* gfortran.dg/gomp/pr118965-1.f90: New.
* gfortran.dg/gomp/pr118965-2.f90: New.

Diff:
---
 gcc/c/c-parser.cc| 44 -
 gcc/cp/parser.cc | 45 +
 gcc/fortran/openmp.cc| 77 +++
 gcc/testsuite/c-c++-common/gomp/append-args-1.c  |  4 +-
 gcc/testsuite/c-c++-common/gomp/append-args-7.c  |  4 +-
 gcc/testsuite/c-c++-common/gomp/append-args-8.c  |  9 +--
 gcc/testsuite/c-c++-common/gomp/append-args-9.c  |  7 ++-
 gcc/testsuite/c-c++-common/gomp/interop-1.c  | 80 
 gcc/testsuite/c-c++-common/gomp/interop-2.c  | 64 ---
 gcc/testsuite/c-c++-common/gomp/interop-3.c  | 26 +++-
 gcc/testsuite/c-c++-common/gomp/interop-4.c  |  8 +--
 gcc/testsuite/c-c++-common/g

[gcc r14-11517] ipa/119067 - bogus TYPE_PRECISION check on VECTOR_TYPE

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:85ed633f26c725bbe5c3a3c6fceada637bf33f7c

commit r14-11517-g85ed633f26c725bbe5c3a3c6fceada637bf33f7c
Author: Richard Biener 
Date:   Mon Mar 3 09:54:15 2025 +0100

ipa/119067 - bogus TYPE_PRECISION check on VECTOR_TYPE

odr_types_equivalent_p can end up using TYPE_PRECISION on vector
types which is a no-go.  The following instead uses TYPE_VECTOR_SUBPARTS
for vector types so we also end up comparing the number of vector elements.

PR ipa/119067
* ipa-devirt.cc (odr_types_equivalent_p): Check
TYPE_VECTOR_SUBPARTS for vectors.

* g++.dg/lto/pr119067_0.C: New testcase.
* g++.dg/lto/pr119067_1.C: Likewise.

(cherry picked from commit f22e89167b3abfbf6d67f42fc4d689d8ffdc1810)

Diff:
---
 gcc/ipa-devirt.cc | 10 +-
 gcc/testsuite/g++.dg/lto/pr119067_0.C | 22 ++
 gcc/testsuite/g++.dg/lto/pr119067_1.C | 10 ++
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index a7ce434bffb4..22805e76c036 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -1259,13 +1259,21 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, 
bool *warned,
   || TREE_CODE (t1) == OFFSET_TYPE
   || POINTER_TYPE_P (t1))
 {
-  if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
+  if (!VECTOR_TYPE_P (t1) && TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
{
  warn_odr (t1, t2, NULL, NULL, warn, warned,
G_("a type with different precision is defined "
   "in another translation unit"));
  return false;
}
+  if (VECTOR_TYPE_P (t1)
+ && maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)))
+   {
+ warn_odr (t1, t2, NULL, NULL, warn, warned,
+   G_("a vector type with different number of elements "
+  "is defined in another translation unit"));
+ return false;
+   }
   if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
{
  warn_odr (t1, t2, NULL, NULL, warn, warned,
diff --git a/gcc/testsuite/g++.dg/lto/pr119067_0.C 
b/gcc/testsuite/g++.dg/lto/pr119067_0.C
new file mode 100644
index ..e0f813ceffed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr119067_0.C
@@ -0,0 +1,22 @@
+/* { dg-lto-do link } */
+/* { dg-skip-if "" { ! { x86_64-*-* i?86-*-* } } } */
+/* { dg-require-effective-target avx2 } */
+/* { dg-require-effective-target shared } */
+/* { dg-lto-options { { -O2 -fPIC -flto } } } */
+/* { dg-extra-ld-options { -shared } } */
+
+#pragma GCC push_options
+#pragma GCC target("avx2")
+typedef char __v32qi __attribute__ ((__vector_size__ (32)));
+struct ff
+{
+  __v32qi t;
+};
+__v32qi g(struct ff a);
+
+__v32qi h(__v32qi a)
+{
+  struct ff t = {a};
+  return g(t);
+}
+#pragma GCC pop_options
diff --git a/gcc/testsuite/g++.dg/lto/pr119067_1.C 
b/gcc/testsuite/g++.dg/lto/pr119067_1.C
new file mode 100644
index ..d8e2935fa24d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr119067_1.C
@@ -0,0 +1,10 @@
+/* { dg-options "-mavx2" } */
+
+typedef char __v32qi __attribute__ ((__vector_size__ (32)));
+struct ff
+{
+  __v32qi t;
+};
+__v32qi g(struct ff a) {
+ return a.t;
+}


[gcc r14-11518] tree-optimization/119096 - bogus conditional reduction vectorization

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:d3e4c092c4f167d3c3ae8aa59d273b0202cef6cf

commit r14-11518-gd3e4c092c4f167d3c3ae8aa59d273b0202cef6cf
Author: Richard Biener 
Date:   Mon Mar 3 14:12:37 2025 +0100

tree-optimization/119096 - bogus conditional reduction vectorization

When we vectorize a .COND_ADD reduction and apply the single-use-def
cycle optimization we can end up chosing the wrong else value for
subsequent .COND_ADD.  The following rectifies this.

PR tree-optimization/119096
* tree-vect-loop.cc (vect_transform_reduction): Use the
correct else value for .COND_fn.

* gcc.dg/vect/pr119096.c: New testcase.

(cherry picked from commit 10e4107dfcf9fe324d0902f16411a75c596dab91)

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr119096.c | 21 +
 gcc/tree-vect-loop.cc|  2 +-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr119096.c 
b/gcc/testsuite/gcc.dg/vect/pr119096.c
new file mode 100644
index ..2c03a5936831
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119096.c
@@ -0,0 +1,21 @@
+#include "tree-vect.h"
+
+long __attribute__((noipa))
+sum(int* A, int* B)
+{
+long total = 0;
+for(int j = 0; j < 16; j++)
+if((A[j] > 0) & (B[j] > 0))
+total += (long)A[j];
+return total;
+}
+int main()
+{
+  int A[16] = { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1 };
+  int B[16] = { };
+  check_vect ();
+  if (sum (A, B) != 0)
+abort ();
+  return 0;
+}
+
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 95f6d06820f3..75fbcdf46d09 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -8660,7 +8660,7 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
new_stmt = gimple_build_call_internal (internal_fn (code),
   op.num_ops,
   vop[0], vop[1], vop[2],
-  vop[1]);
+  vop[reduc_index]);
  else
new_stmt = gimple_build_assign (vec_dest, tree_code (op.code),
vop[0], vop[1], vop[2]);


[gcc r14-11503] lto/91299 - weak definition inlined with LTO

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:e3290933ead698742f59e4abc4da694e73191203

commit r14-11503-ge3290933ead698742f59e4abc4da694e73191203
Author: Richard Biener 
Date:   Fri Feb 28 14:09:29 2025 +0100

lto/91299 - weak definition inlined with LTO

The following fixes a thinko in the handling of interposed weak
definitions which confused the interposition check in
get_availability by setting DECL_EXTERNAL too early.

PR lto/91299
gcc/lto/
* lto-symtab.cc (lto_symtab_merge_symbols): Set DECL_EXTERNAL
only after calling get_availability.

gcc/testsuite/
* gcc.dg/lto/pr91299_0.c: New testcase.
* gcc.dg/lto/pr91299_1.c: Likewise.

(cherry picked from commit bc34db5b12e008f6ec4fdf4ebd22263c8617e5e3)

Diff:
---
 gcc/lto/lto-symtab.cc|  2 +-
 gcc/testsuite/gcc.dg/lto/pr91299_0.c | 16 
 gcc/testsuite/gcc.dg/lto/pr91299_1.c |  6 ++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gcc/lto/lto-symtab.cc b/gcc/lto/lto-symtab.cc
index a40218beac55..2e2eb4bd8148 100644
--- a/gcc/lto/lto-symtab.cc
+++ b/gcc/lto/lto-symtab.cc
@@ -1016,7 +1016,6 @@ lto_symtab_merge_symbols (void)
  || node->resolution == LDPR_RESOLVED_EXEC
  || node->resolution == LDPR_RESOLVED_DYN))
{
- DECL_EXTERNAL (node->decl) = 1;
  /* If alias to local symbol was preempted by external definition,
 we know it is not pointing to the local symbol.  Remove it.  */
  if (node->alias
@@ -1042,6 +1041,7 @@ lto_symtab_merge_symbols (void)
  node->remove_all_references ();
}
}
+ DECL_EXTERNAL (node->decl) = 1;
}
 
  if (!(cnode = dyn_cast  (node))
diff --git a/gcc/testsuite/gcc.dg/lto/pr91299_0.c 
b/gcc/testsuite/gcc.dg/lto/pr91299_0.c
new file mode 100644
index ..d9a8b21d6b84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr91299_0.c
@@ -0,0 +1,16 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O2 -flto } } } */
+
+__attribute__((weak)) int get_t(void)
+{
+  return 0;
+}
+
+int a;
+int main(void)
+{
+  a = get_t();
+  if (a != 1)
+__builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/pr91299_1.c 
b/gcc/testsuite/gcc.dg/lto/pr91299_1.c
new file mode 100644
index ..29a28520f7b5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr91299_1.c
@@ -0,0 +1,6 @@
+/* { dg-options "-fno-lto" } */
+
+int get_t(void)
+{
+return 1;
+}


[gcc r12-11013] libstdc++: Teach optimizer that empty COW strings are empty [PR107087]

2025-04-02 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:f3878885b1aa4ab96b6905d9485a1261934e291b

commit r12-11013-gf3878885b1aa4ab96b6905d9485a1261934e291b
Author: Jonathan Wakely 
Date:   Fri Mar 31 13:44:04 2023 +0100

libstdc++: Teach optimizer that empty COW strings are empty [PR107087]

The compiler doesn't know about the invariant that the _S_empty_rep()
object is immutable and so _M_length and _M_refcount are always zero.
This means that we get warnings about writing possibly-non-zero length
strings into buffers that can't hold them. If we teach the compiler that
the empty rep is always zero length, it knows it can be copied into any
buffer.

For Stage 1 we might want to also consider adding this to capacity():

if (_S_empty_rep()._M_capacity != 0)
  __builtin_unreachable();

And this to _Rep::_M_is_leaked() and _Rep::_M_is_shared():

  if (_S_empty_rep()._M_refcount != 0)
__builtin_unreachable();

libstdc++-v3/ChangeLog:

PR tree-optimization/107087
* include/bits/cow_string.h (basic_string::size()): Add
optimizer hint that _S_empty_rep()._M_length is always zero.
(basic_string::length()): Call size().

(cherry picked from commit 4969dcd2b7a94ce6c0d07225b21b5f3c040a4902)

Diff:
---
 libstdc++-v3/include/bits/cow_string.h | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/cow_string.h 
b/libstdc++-v3/include/bits/cow_string.h
index 6dd238834298..f79fd879582f 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -909,17 +909,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 public:
   // Capacity:
+
   ///  Returns the number of characters in the string, not including any
   ///  null-termination.
   size_type
   size() const _GLIBCXX_NOEXCEPT
-  { return _M_rep()->_M_length; }
+  {
+#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && __OPTIMIZE__
+   if (_S_empty_rep()._M_length != 0)
+ __builtin_unreachable();
+#endif
+   return _M_rep()->_M_length;
+  }
 
   ///  Returns the number of characters in the string, not including any
   ///  null-termination.
   size_type
   length() const _GLIBCXX_NOEXCEPT
-  { return _M_rep()->_M_length; }
+  { return size(); }
 
   ///  Returns the size() of the largest possible %string.
   size_type


[gcc r15-9150] libstdc++, testsuite, Darwin: Prune a new linker warning present form XCode 16.

2025-04-02 Thread Iain D Sandoe via Libstdc++-cvs
https://gcc.gnu.org/g:efe72d9f050a72ffb698adef8434afae1849dcff

commit r15-9150-gefe72d9f050a72ffb698adef8434afae1849dcff
Author: Iain Sandoe 
Date:   Wed Apr 2 14:38:38 2025 +0100

libstdc++, testsuite, Darwin: Prune a new linker warning present form XCode 
16.

Darwin's linker now warns when duplicate rpaths are presented - which
happens when we emit duplicate '-B' paths.  In principle, we should avoid
this in the test-suite, however at present we tend to have duplicates
because different parts of the machinery add them.  At some point, it might
be nice to have an "add_option_if_missing" and apply that across the whole
of the test infra. However this is not something for late in stage 4.  So
the solution here is to prune the warning - the effect of the duplicate in
the libstdc++ testsuite is not important; it will make the exes very 
slightly
larger but it won't alter the paths that are presented for loading the
runtimes.

libstdc++-v3/ChangeLog:

* testsuite/lib/prune.exp: Prune ld warning about duplicatei
rpaths.

Signed-off-by: Iain Sandoe 

Diff:
---
 libstdc++-v3/testsuite/lib/prune.exp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libstdc++-v3/testsuite/lib/prune.exp 
b/libstdc++-v3/testsuite/lib/prune.exp
index 416e851614ba..a9a29937e43a 100644
--- a/libstdc++-v3/testsuite/lib/prune.exp
+++ b/libstdc++-v3/testsuite/lib/prune.exp
@@ -77,6 +77,9 @@ proc libstdc++-dg-prune { system text } {
 # Ignore harmless warnings from Xcode 4+.
 regsub -all "(^|\n)\[^\n\]*ld: warning: could not create compact unwind 
for\[^\n\]*" $text "" text
 
+# Ignore duplicate path warnings from Xcode 16+.
+regsub -all "(^|\n)\[^\n\]*ld: warning: duplicate -rpath\[^\n\]*" $text "" 
text
+
 # Ignore dsymutil warning (tool bug is actually in the linker)
 regsub -all "(^|\n)\[^\n\]*could not find object file symbol for 
symbol\[^\n\]*" $text "" text


[gcc r15-9151] config, toplevel, Darwin: Pass -B instead of -L to C++ commands.

2025-04-02 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:17ed44c96f6e5c0cc02d8cb29ff5943dd30ab3c1

commit r15-9151-g17ed44c96f6e5c0cc02d8cb29ff5943dd30ab3c1
Author: Iain Sandoe 
Date:   Mon Mar 31 07:02:54 2025 +0100

config, toplevel, Darwin: Pass -B instead of -L to C++ commands.

Darwin from 10.11 needs embedded rpaths to find the correct libraries at
runtime.  Recent increases in hardening have made it such that the dynamic
loader will no longer fall back to using an installed libstdc++ when the
(new) linked one is not found.  This means we fail configure tests (that
should pass) for runtimes that use C++.

We can resolve this by passing '-B' to the C++ command lines instead of '-L'
(-B implies -L on Darwin, but also causes a corresponding embedded rpath).

ChangeLog:

* configure: Regenerate.
* configure.ac: Use -B instead of -L to specifiy the C++ runtime
paths on Darwin.

Signed-off-by: Iain Sandoe 

Diff:
---
 configure| 100 +--
 configure.ac |  16 --
 2 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/configure b/configure
index 036142a8d061..bf574efd1d82 100755
--- a/configure
+++ b/configure
@@ -19081,7 +19081,101 @@ $as_echo "pre-installed" >&6; }
   fi
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the target 
c++" >&5
+case $target in
+  *-*-darwin*)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the target 
c++" >&5
+$as_echo_n "checking where to find the target c++... " >&6; }
+if test "x${build}" != "x${host}" ; then
+  if expr "x$CXX_FOR_TARGET" : "x/" > /dev/null; then
+# We already found the complete path
+ac_dir=`dirname $CXX_FOR_TARGET`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: pre-installed in $ac_dir" 
>&5
+$as_echo "pre-installed in $ac_dir" >&6; }
+  else
+# Canadian cross, just use what we found
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: pre-installed" >&5
+$as_echo "pre-installed" >&6; }
+  fi
+else
+  ok=yes
+  case " ${configdirs} " in
+*" gcc "*) ;;
+*) ok=no ;;
+  esac
+  case ,${enable_languages}, in
+*,c++,*) ;;
+*) ok=no ;;
+  esac
+  if test $ok = yes; then
+# An in-tree tool is available and we can use it
+CXX_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/xg++ -B$$r/$(HOST_SUBDIR)/gcc/ 
-nostdinc++ `if test -f 
$$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags; then $(SHELL) 
$$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags --build-includes; 
else echo -funconfigured-libstdc++-v3 ; fi` 
-B$$r/$(TARGET_SUBDIR)/libstdc++-v3/src 
-B$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs 
-B$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: just compiled" >&5
+$as_echo "just compiled" >&6; }
+  elif expr "x$CXX_FOR_TARGET" : "x/" > /dev/null; then
+# We already found the complete path
+ac_dir=`dirname $CXX_FOR_TARGET`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: pre-installed in $ac_dir" 
>&5
+$as_echo "pre-installed in $ac_dir" >&6; }
+  elif test "x$target" = "x$host"; then
+# We can use an host tool
+CXX_FOR_TARGET='$(CXX)'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: host tool" >&5
+$as_echo "host tool" >&6; }
+  else
+# We need a cross tool
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: pre-installed" >&5
+$as_echo "pre-installed" >&6; }
+  fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the target 
c++ for libstdc++" >&5
+$as_echo_n "checking where to find the target c++ for libstdc++... " >&6; }
+if test "x${build}" != "x${host}" ; then
+  if expr "x$RAW_CXX_FOR_TARGET" : "x/" > /dev/null; then
+# We already found the complete path
+ac_dir=`dirname $RAW_CXX_FOR_TARGET`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: pre-installed in $ac_dir" 
>&5
+$as_echo "pre-installed in $ac_dir" >&6; }
+  else
+# Canadian cross, just use what we found
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: pre-installed" >&5
+$as_echo "pre-installed" >&6; }
+  fi
+else
+  ok=yes
+  case " ${configdirs} " in
+*" gcc "*) ;;
+*) ok=no ;;
+  esac
+  case ,${enable_languages}, in
+*,c++,*) ;;
+*) ok=no ;;
+  esac
+  if test $ok = yes; then
+# An in-tree tool is available and we can use it
+RAW_CXX_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/xgcc -shared-libgcc 
-B$$r/$(HOST_SUBDIR)/gcc -nostdinc++ -B$$r/$(TARGET_SUBDIR)/libstdc++-v3/src 
-B$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs 
-B$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: just compiled" >&5
+$as_echo "just compiled" >&6; }
+  elif expr "x$RAW_CXX_FOR_TARGET" : "x/" > /dev/null; then
+# We already found the complete path
+ac_dir=`dirname $RAW_CXX_FOR_TARGET`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: pre-installed in $ac_dir" 
>&5
+$as_echo "pre-installed 

[gcc r15-9161] RISC-V: Fix vec_duplicate[bimode] expander [PR119572].

2025-04-02 Thread Robin Dapp via Gcc-cvs
https://gcc.gnu.org/g:716d39f0a248c1003033e6a312c736180790ef70

commit r15-9161-g716d39f0a248c1003033e6a312c736180790ef70
Author: Robin Dapp 
Date:   Tue Apr 1 21:17:54 2025 +0200

RISC-V: Fix vec_duplicate[bimode] expander [PR119572].

Since r15-9062-g70391e3958db79 we perform vector bitmask initialization
via the vec_duplicate expander directly.  This triggered a latent bug in
ours where we missed to mask out the single bit which resulted in an
execution FAIL of pr119114.c

The attached patch adds the 1-masking of the broadcast operand.

PR target/119572

gcc/ChangeLog:

* config/riscv/autovec.md: Mask broadcast value.

Diff:
---
 gcc/config/riscv/autovec.md | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f53ed3a5e3fd..9e51e3ce6a30 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -330,7 +330,15 @@
   {
 poly_int64 nunits = GET_MODE_NUNITS (mode);
 machine_mode mode = riscv_vector::get_vector_mode (QImode, nunits).require 
();
-rtx dup = expand_vector_broadcast (mode, operands[1]);
+
+/* The 1-bit mask is in a QImode register, make sure we only use the last
+   bit.  See also PR119114 and the respective vec_init expander.  */
+rtx tmp = gen_reg_rtx (Xmode);
+emit_insn
+  (gen_rtx_SET (tmp, gen_rtx_AND (Xmode, gen_lowpart (Xmode, operands[1]),
+ CONST1_RTX (Xmode;
+
+rtx dup = expand_vector_broadcast (mode, gen_lowpart (QImode, tmp));
 riscv_vector::expand_vec_cmp (operands[0], NE, dup, CONST0_RTX (mode));
 DONE;
   }


[gcc r15-9162] d: Fix error using UFCS in a speculative context

2025-04-02 Thread Iain Buclaw via Gcc-cvs
https://gcc.gnu.org/g:a66de265ab865aacbb6c4957916605c7bac7ff48

commit r15-9162-ga66de265ab865aacbb6c4957916605c7bac7ff48
Author: Iain Buclaw 
Date:   Wed Apr 2 21:21:14 2025 +0200

d: Fix error using UFCS in a speculative context

This reverts a change in the upstream D implementation of the compiler,
as it is no longer necessary since another fix for opDispatch got
applied in the same area (merged in r12-6003-gfd43568cc54e17).

gcc/d/ChangeLog:

* dmd/MERGE: Merge upstream dmd ed17b3e95d.

Reviewed-on: https://github.com/dlang/dmd/pull/21132

Diff:
---
 gcc/d/dmd/MERGE|  2 +-
 gcc/d/dmd/expressionsem.d  | 11 +---
 .../gdc.test/compilable/imports/test21098_phobos.d | 77 ++
 .../gdc.test/compilable/imports/test21098b.d   | 12 
 gcc/testsuite/gdc.test/compilable/test21098.d  |  4 ++
 5 files changed, 97 insertions(+), 9 deletions(-)

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 00c85187b6de..bd297b612c4e 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-c6863be7206eef3c393726363a480baf0a0c6530
+ed17b3e95dc3fc3264a4c91843da824f5541f3e1
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 04efa1f86f13..b0278cbaca1b 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -1247,6 +1247,9 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
 }
 else
 {
+if (arrayExpressionSemantic(ce.arguments.peekSlice(), sc))
+return ErrorExp.get();
+
 if (Expression ey = die.dotIdSemanticProp(sc, 1))
 {
 if (ey.op == EXP.error)
@@ -1254,19 +1257,11 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
 ce.e1 = ey;
 if (isDotOpDispatch(ey))
 {
-// even opDispatch and UFCS must have valid arguments,
-// so now that we've seen indication of a problem,
-// check them for issues.
-Expressions* originalArguments = 
Expression.arraySyntaxCopy(ce.arguments);
-
 const errors = global.startGagging();
 e = ce.expressionSemantic(sc);
 if (!global.endGagging(errors))
 return e;
 
-if (arrayExpressionSemantic(originalArguments.peekSlice(), 
sc))
-return ErrorExp.get();
-
 /* fall down to UFCS */
 }
 else
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test21098_phobos.d 
b/gcc/testsuite/gdc.test/compilable/imports/test21098_phobos.d
new file mode 100644
index ..29c77eb047af
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/test21098_phobos.d
@@ -0,0 +1,77 @@
+struct Nullable(T)
+{
+static struct DontCallDestructorT
+{
+T payload;
+}
+
+DontCallDestructorT _value;
+
+string toString() const
+{
+Appender!string app;
+formatValueImpl(app, _value);
+return null;
+}
+}
+
+
+
+struct Appender(A)
+{
+InPlaceAppender!A impl;
+}
+
+struct InPlaceAppender(T)
+{
+static void toStringImpl(const T[] data)
+{
+string app;
+formatValue(app, data);
+}
+}
+
+
+
+void formatValueImpl(Writer, T)(Writer, const(T)) {}
+
+void formatValueImpl(Writer, T)(Writer w, T obj)
+if (is(T == U[], U))
+{
+formatValue(w, obj[0]);
+}
+
+enum HasToStringResult
+{
+none,
+bla
+}
+
+template hasToString(T)
+{
+static if (is(typeof(
+(T val) {
+val.toString(s);
+})))
+enum hasToString = HasToStringResult.bla;
+else
+enum hasToString = HasToStringResult.none;
+}
+
+void formatValueImpl(Writer, T)(ref Writer w, T val)
+if (is(T == struct) || is(T == union))
+{
+static if (hasToString!T)
+int dummy;
+formatElement(w, val.tupleof);
+}
+
+void formatElement(Writer, T)(Writer w, T val)
+{
+formatValueImpl(w, val);
+}
+
+void formatValue(Writer, T)(Writer w, T val)
+{
+formatValueImpl(w, val);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test21098b.d 
b/gcc/testsuite/gdc.test/compilable/imports/test21098b.d
new file mode 100644
index ..74c9fa80c87e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/test21098b.d
@@ -0,0 +1,12 @@
+import imports.test21098_phobos : Appender, Nullable;
+
+struct Type {
+Nullable!(Type[]) templateArgs;
+}
+
+Type[] parseDeclarations() {
+Appender!(Type[]) members;
+return null;
+}
+
+enum ast = parseDeclarations();
diff --git a/gcc/testsuite/gdc.test/compilable/test21098.d 
b/gcc/testsuite/gdc.test/compilable/test21098.d
new file mode 100644
index ..9b02b7b4d6e3
--- /dev/n

[gcc r12-11012] libstdc++: Avoid aliasing violation in std::valarray [PR99117]

2025-04-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:8250987299d01ff318b73a02e4ba245afd46b64b

commit r12-11012-g8250987299d01ff318b73a02e4ba245afd46b64b
Author: Jonathan Wakely 
Date:   Thu Feb 8 13:59:42 2024 +

libstdc++: Avoid aliasing violation in std::valarray [PR99117]

The call to __valarray_copy constructs an _Array object to refer to
this->_M_data but that means that accesses to this->_M_data are through
a restrict-qualified pointer. This leads to undefined behaviour when
copying from an _Expr object that actually aliases this->_M_data.

Replace the call to __valarray_copy with a plain loop. I think this
removes the only use of that overload of __valarray_copy, so it could
probably be removed. I haven't done that here.

libstdc++-v3/ChangeLog:

PR libstdc++/99117
* include/std/valarray (valarray::operator=(const _Expr&)):
Use loop to copy instead of __valarray_copy with _Array.
* testsuite/26_numerics/valarray/99117.cc: New test.

(cherry picked from commit b58f0e5216a3053486e7f1aa96c3f2443b14d630)

Diff:
---
 libstdc++-v3/include/std/valarray|  8 +++-
 libstdc++-v3/testsuite/26_numerics/valarray/99117.cc | 17 +
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/valarray 
b/libstdc++-v3/include/std/valarray
index 32e6e7e8a76b..d49959772513 100644
--- a/libstdc++-v3/include/std/valarray
+++ b/libstdc++-v3/include/std/valarray
@@ -838,7 +838,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 630. arrays of valarray.
   if (_M_size == __e.size())
-   std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
+   {
+ // Copy manually instead of using __valarray_copy, because __e might
+ // alias _M_data and the _Array param type of __valarray_copy uses
+ // restrict which doesn't allow aliasing.
+ for (size_t __i = 0; __i < _M_size; ++__i)
+   _M_data[__i] = __e[__i];
+   }
   else
{
  if (_M_data)
diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/99117.cc 
b/libstdc++-v3/testsuite/26_numerics/valarray/99117.cc
new file mode 100644
index ..81621bd079a1
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/valarray/99117.cc
@@ -0,0 +1,17 @@
+// { dg-do run { target c++11 } }
+
+// PR libstdc++/99117 cannot accumulate std::valarray
+
+#include 
+#include 
+#include 
+
+int main()
+{
+std::vector> v = {{1,1}, {2,2}};
+std::valarray sum(2);
+for (const auto& e : v)
+  sum = sum + e;
+VERIFY(sum[0]==3);
+VERIFY(sum[1]==3);
+}


[gcc r15-9149] tree-optimization/119586 - aligned access to unaligned data

2025-04-02 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:574c59cfe6e29c9e5758988b75c2e7ab6edc37da

commit r15-9149-g574c59cfe6e29c9e5758988b75c2e7ab6edc37da
Author: Richard Biener 
Date:   Wed Apr 2 13:12:58 2025 +0200

tree-optimization/119586 - aligned access to unaligned data

The following reverts parts of r15-8047 which assesses alignment
analysis for VMAT_STRIDED_SLP is correct by using aligned accesses
where allowed by it.  As the PR shows this analysis is still incorrect,
so revert back to assuming we got it wrong.

PR tree-optimization/119586
* tree-vect-stmts.cc (vectorizable_load): Assume we got
alignment analysis for VMAT_STRIDED_SLP wrong.
(vectorizable_store): Likewise.

* gcc.dg/vect/pr119586.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr119586.c | 21 +
 gcc/tree-vect-stmts.cc   | 21 +
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr119586.c 
b/gcc/testsuite/gcc.dg/vect/pr119586.c
new file mode 100644
index ..04a00ef131e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119586.c
@@ -0,0 +1,21 @@
+#include "tree-vect.h"
+
+void __attribute__((noipa)) foo (long *) {}
+void __attribute__((noipa))
+d()
+{
+  long e[6][8][5];
+  for (int b = 0; b < 6; b++)
+for (int c = 0; c < 8; c++)
+  {
+e[b][c][0] = 1;
+e[b][c][1] = 1;
+e[b][c][4] = 1;
+  }
+  foo (&e[0][0][0]);
+}
+int main()
+{
+  check_vect ();
+  d();
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 8bd5ea96667d..3005ae6eaaea 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -8906,10 +8906,17 @@ vectorizable_store (vec_info *vinfo,
}
}
  unsigned align;
- if (alignment_support_scheme == dr_aligned)
-   align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
- else
-   align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
+ /* ???  We'd want to use
+  if (alignment_support_scheme == dr_aligned)
+align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
+since doing that is what we assume we can in the above checks.
+But this interferes with groups with gaps where for example
+VF == 2 makes the group in the unrolled loop aligned but the
+fact that we advance with step between the two subgroups
+makes the access to the second unaligned.  See PR119586.
+We have to anticipate that here or adjust code generation to
+avoid the misaligned loads by means of permutations.  */
+ align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
  /* Alignment is at most the access size if we do multiple stores.  */
  if (nstores > 1)
align = MIN (tree_to_uhwi (TYPE_SIZE_UNIT (ltype)), align);
@@ -10884,10 +10891,8 @@ vectorizable_load (vec_info *vinfo,
}
}
  unsigned align;
- if (alignment_support_scheme == dr_aligned)
-   align = known_alignment (DR_TARGET_ALIGNMENT (first_dr_info));
- else
-   align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
+ /* ???  The above is still wrong, see vectorizable_store.  */
+ align = dr_alignment (vect_dr_behavior (vinfo, first_dr_info));
  /* Alignment is at most the access size if we do multiple loads.  */
  if (nloads > 1)
align = MIN (tree_to_uhwi (TYPE_SIZE_UNIT (ltype)), align);


[gcc r13-9486] libstdc++: Fix bogus -Wstringop-overflow in std::vector::insert [PR117983]

2025-04-02 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:8f633fe7c7d03ed6c0ce029a831037a6274a0882

commit r13-9486-g8f633fe7c7d03ed6c0ce029a831037a6274a0882
Author: Jonathan Wakely 
Date:   Fri Mar 28 22:00:38 2025 +

libstdc++: Fix bogus -Wstringop-overflow in std::vector::insert [PR117983]

This was fixed on trunk by r15-4473-g3abe751ea86e34, but that isn't
suitable for backporting. Instead, just add another unreachable
condition in std::vector::_M_range_insert so the compiler knows this
memcpy doesn't use a length originating from a negative ptrdiff_t
converted to a very positive size_t.

libstdc++-v3/ChangeLog:

PR libstdc++/117983
* include/bits/vector.tcc (vector::_M_range_insert): Add
unreachable condition to tell the compiler begin() <= end().
* testsuite/23_containers/vector/modifiers/insert/117983.cc: New
test.

Reviewed-by: Tomasz KamiƄski 

(cherry picked from commit 878812b6f6905774ab37cb78903e3e11bf1c508c)

Diff:
---
 libstdc++-v3/include/bits/vector.tcc|  2 ++
 .../23_containers/vector/modifiers/insert/117983.cc | 17 +
 2 files changed, 19 insertions(+)

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index c762dbf798f6..ddbfde447f62 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -799,6 +799,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// reachable.
pointer __old_start = this->_M_impl._M_start;
pointer __old_finish = this->_M_impl._M_finish;
+   if ((__old_finish - __old_start) < 0)
+ __builtin_unreachable();
 
const size_type __len =
  _M_check_len(__n, "vector::_M_range_insert");
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/117983.cc 
b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/117983.cc
new file mode 100644
index ..e6027a677eed
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/117983.cc
@@ -0,0 +1,17 @@
+// { dg-options "-O3 -Werror=stringop-overflow" }
+// { dg-do compile }
+
+// PR libstdc++/117983
+// -Wstringop-overflow false positive for __builtin_memmove from vector::insert
+
+#include 
+
+typedef std::vector bytes;
+
+void push(bytes chunk, bytes& data) {
+  if (data.empty()) {
+data.swap(chunk);
+  } else {
+data.insert(data.end(), chunk.begin(), chunk.end());
+  }
+}


[gcc r13-9487] libstdc++: Fix -Wstringop-overread warning in std::vector [PR114758]

2025-04-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:d1929ba18c1e4f0fa4212ec2181f8345896bb7e8

commit r13-9487-gd1929ba18c1e4f0fa4212ec2181f8345896bb7e8
Author: Jonathan Wakely 
Date:   Fri Mar 28 15:41:41 2025 +

libstdc++: Fix -Wstringop-overread warning in std::vector [PR114758]

As in r13-4393-gcca06f0d6d76b0 and a few other commits, we can avoid
bogus warnings in std::vector by hoisting some loads to before the
allocation that calls operator new. This means that the compiler has
enough info to remove the dead branches that trigger bogus warnings.

On trunk this is only needed with -fno-assume-sane-operators-new-delete
but it will help on the branches where that option doesn't exist.

libstdc++-v3/ChangeLog:

PR libstdc++/114758
* include/bits/vector.tcc (vector::_M_fill_insert):
Hoist loads of begin() and end() before allocation.
* testsuite/23_containers/vector/bool/capacity/114758.cc: New
test.

Reviewed-by: Tomasz KamiƄski 

(cherry picked from commit 1f6c19f307c8de9830130a0ba071c24e3835beb3)

Diff:
---
 libstdc++-v3/include/bits/vector.tcc |  5 +++--
 .../testsuite/23_containers/vector/bool/capacity/114758.cc   | 12 
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index ddbfde447f62..16ccfc7c02ea 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -876,11 +876,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
  const size_type __len = 
_M_check_len(__n, "vector::_M_fill_insert");
+ iterator __begin = begin(), __end = end();
  _Bit_pointer __q = this->_M_allocate(__len);
  iterator __start(std::__addressof(*__q), 0);
- iterator __i = _M_copy_aligned(begin(), __position, __start);
+ iterator __i = _M_copy_aligned(__begin, __position, __start);
  std::fill(__i, __i + difference_type(__n), __x);
- iterator __finish = std::copy(__position, end(),
+ iterator __finish = std::copy(__position, __end,
__i + difference_type(__n));
  this->_M_deallocate();
  this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/114758.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/114758.cc
new file mode 100644
index ..43efdef7e1d2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/114758.cc
@@ -0,0 +1,12 @@
+// { dg-options "-O3 -Werror=stringop-overread" }
+// { dg-do compile }
+
+// Bug libstdc++/114758 The layout of a std::vector reports a warning
+
+#include 
+
+void pr114758(std::vector& v)
+{
+  v.resize(3);
+  v = std::vector(3, false);
+}


[gcc r15-9157] hpux: Only use long long when __cplusplus >= 201103L

2025-04-02 Thread John David Anglin via Gcc-cvs
https://gcc.gnu.org/g:6d18be71d3c164dfc8a2aa0f53a15b2ec2af2182

commit r15-9157-g6d18be71d3c164dfc8a2aa0f53a15b2ec2af2182
Author: John David Anglin 
Date:   Wed Apr 2 14:50:53 2025 -0400

hpux: Only use long long when __cplusplus >= 201103L

2025-04-02  John David Anglin  

libstdc++-v3/ChangeLog:
* config/os/hpux/os_defines.h: Only use long long when
__cplusplus >= 201103L.

Diff:
---
 libstdc++-v3/config/os/hpux/os_defines.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/config/os/hpux/os_defines.h 
b/libstdc++-v3/config/os/hpux/os_defines.h
index 30bd4c7ba14d..d3a6c5ab1426 100644
--- a/libstdc++-v3/config/os/hpux/os_defines.h
+++ b/libstdc++-v3/config/os/hpux/os_defines.h
@@ -57,7 +57,7 @@
We also force _GLIBCXX_USE_LONG_LONG here so that we don't have
to bastardize configure to deal with this sillyness.  */
 
-#ifdef __cplusplus
+#if __cplusplus >= 201103L
 namespace std
 {
   extern "C"


[gcc r15-9156] cobol: Plug memory leak caused by intermediate_e stack-frame variables. [PR119521]

2025-04-02 Thread Robert Dubner via Gcc-cvs
https://gcc.gnu.org/g:29ac3adb8f72ecbe734d535b1015fe8b411316cb

commit r15-9156-g29ac3adb8f72ecbe734d535b1015fe8b411316cb
Author: Bob Dubner 
Date:   Wed Apr 2 12:18:08 2025 -0400

cobol: Plug memory leak caused by intermediate_e stack-frame variables. 
[PR119521]

COBOL variables with attribute intermediate_e are being allocated on
the stack frame, but their data was assigned using malloc(), without
a corresponding call to free().  For numerics, the problem is solved
with a fixed allocation of sixteen bytes for the cblc_field_t::data
member (sixteen is big enough for all data types) and with a fixed
allocation of 8,192 bytes for the alphanumeric type.

In use, the intermediate numeric data types are "shrunk" to the minimum
applicable size.  The intermediate alphanumerics, generally used as
destination targets for functions, are trimmed as well.

gcc/cobol

PR cobol/119521
* genapi.cc: (parser_division): Change comment.
(parser_symbol_add): Change intermediate_t handling.
* parse.y: Multiple changes to new_alphanumeric() calls.
* parse_ante.h: Establish named constant for date function
calls.  Change declaration of new_alphanumeric() function.
* symbols.cc: (new_temporary_impl): Use named constant
for default size of temporary alphanumerics.
* symbols.h: Establish MAXIMUM_ALPHA_LENGTH constant.

libgcobol

PR cobol/119521
* intrinsic.cc: (__gg__reverse): Trim final result for 
intermediate_e.
* libgcobol.cc: (__gg__adjust_dest_size): Abort on attempt to 
increase
the size of a result.  (__gg__module_name): Formatting.
__gg__reverse(): Resize only intermediates

Diff:
---
 gcc/cobol/genapi.cc| 85 --
 gcc/cobol/parse.y  | 73 +--
 gcc/cobol/parse_ante.h |  3 +-
 gcc/cobol/symbols.cc   |  3 +-
 gcc/cobol/symbols.h|  6 
 libgcobol/intrinsic.cc |  4 +++
 libgcobol/libgcobol.cc |  8 +++--
 7 files changed, 94 insertions(+), 88 deletions(-)

diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index 92ab460e2c0b..4d958cfc0d4b 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -6647,7 +6647,10 @@ parser_division(cbl_division_t division,
 
   if( args[i].refer.field->attr & any_length_e )
 {
-//gg_printf("side channel 0x%lx\n", 
gg_array_value(var_decl_call_parameter_lengths, rt_i), NULL_TREE);
+// gg_printf("side channel: Length of \"%s\" is %ld\n", 
+  // member(args[i].refer.field->var_decl_node, "name"),
+  // gg_array_value(var_decl_call_parameter_lengths, 
rt_i), 
+  // NULL_TREE);
 
 // Get the length from the global lengths[] side channel.  Don't
 // forget to use the length mask on the table value.
@@ -16753,55 +16756,47 @@ parser_symbol_add(struct cbl_field_t *new_var )
 
 if( bytes_to_allocate )
   {
-  if(new_var->attr & (intermediate_e)
-  && new_var->type != FldLiteralN
-  && new_var->type != FldLiteralA )
+  // We need a unique name for the allocated data for this COBOL 
variable:
+  char achDataName[256];
+  if( new_var->attr & external_e )
 {
-// We'll malloc() data in initialize_variable
-data_area = null_pointer_node;
+sprintf(achDataName, "%s", new_var->name);
+}
+  else if( new_var->name[0] == '_' )
+{
+// Avoid doubling up on leading underscore
+sprintf(achDataName,
+"%s_data_%lu",
+new_var->name,
+sv_data_name_counter++);
 }
   else
 {
-// We need a unique name for the allocated data for this COBOL 
variable:
-char achDataName[256];
-if( new_var->attr & external_e )
-  {
-  sprintf(achDataName, "%s", new_var->name);
-  }
-else if( new_var->name[0] == '_' )
-  {
-  // Avoid doubling up on leading underscore
-  sprintf(achDataName,
-  "%s_data_%lu",
-  new_var->name,
-  sv_data_name_counter++);
-  }
-else
-  {
-  sprintf(achDataName,
-  "_%s_data_%lu",
-  new_var->name,
-  sv_data_name_counter++);
-  }
+sprintf(achDataName,
+"_%s_data_%lu",
+new_var->name,
+sv_data_name_counter++);
+}
 
-if( new_var->attr & external_e )
-  {
-  tree array_ty

[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa-dce: pass execute tests

2025-04-02 Thread Ondrej Machota via Gcc-cvs
https://gcc.gnu.org/g:753dc2e51076204b3da0728a4525f3a0e954309f

commit 753dc2e51076204b3da0728a4525f3a0e954309f
Author: Ondƙej Machota 
Date:   Wed Apr 2 20:41:24 2025 +0200

rtl-ssa-dce: pass execute tests

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

diff --git a/gcc/dce.cc b/gcc/dce.cc
index b4ea199c6d76..6221e3b39910 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1416,7 +1416,7 @@ bool is_rtx_insn_prelive(rtx_insn *insn) {
 bool is_prelive(insn_info *insn)
 {
   /* Phi insns are never prelive, bb head + end also are artificial */
-  if (insn->is_artificial())
+  if (insn->is_artificial() || insn->is_debug_insn())
 return false;
 
   gcc_assert (insn->is_real());
@@ -1574,7 +1574,7 @@ rtl_ssa_dce_sweep(std::unordered_set marked)
 /* Artificial and marked insns cannot be deleted.
There is a slight problem with phis, because we might want to delete
some phi nodes from phi insn. */
-if (insn->is_artificial() || marked.count(insn) > 0)
+if (insn->is_artificial() || insn->is_debug_insn() || marked.count(insn) > 
0)
   continue;
 
 auto change = insn_change::delete_insn(insn);


[gcc r15-9158] Skip g++.dg/abi/abi-tag18a.C on hppa*-*-hpux*

2025-04-02 Thread John David Anglin via Gcc-cvs
https://gcc.gnu.org/g:aeca210ecfb97ae7f3d0de69276ec77b65ea34e9

commit r15-9158-gaeca210ecfb97ae7f3d0de69276ec77b65ea34e9
Author: John David Anglin 
Date:   Wed Apr 2 14:58:01 2025 -0400

Skip g++.dg/abi/abi-tag18a.C on hppa*-*-hpux*

2025-04-02  John David Anglin  

gcc/testsuite/ChangeLog:

* g++.dg/abi/abi-tag18a.C: Skip on hppa*-*-hpux*.

Diff:
---
 gcc/testsuite/g++.dg/abi/abi-tag18a.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/abi/abi-tag18a.C 
b/gcc/testsuite/g++.dg/abi/abi-tag18a.C
index c6fb1607a418..392abf78062a 100644
--- a/gcc/testsuite/g++.dg/abi/abi-tag18a.C
+++ b/gcc/testsuite/g++.dg/abi/abi-tag18a.C
@@ -1,4 +1,4 @@
-// { dg-skip-if "PR 70349" { hppa*-*-hpux* && { ! lp64 } } }
+// { dg-skip-if "PR 70349" { hppa*-*-hpux* } }
 // { dg-options "-fabi-version=9 -fno-implicit-constexpr" }
 // { dg-final { scan-assembler "_Z1fB7__test1v" } }
 // { dg-final { scan-assembler "_ZZ1fB7__test1vEN1T1gB7__test2Ev" } }


[gcc r15-9145] tailc: Don't fail musttail calls if they use or could use local arguments, instead warn [PR119376]

2025-04-02 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:634215cdc3c569f9a9a247dcd4d9a4d6ce68ad57

commit r15-9145-g634215cdc3c569f9a9a247dcd4d9a4d6ce68ad57
Author: Jakub Jelinek 
Date:   Wed Apr 2 10:51:42 2025 +0200

tailc: Don't fail musttail calls if they use or could use local arguments, 
instead warn [PR119376]

As discussed here and in bugzilla, [[clang::musttail]] attribute in clang
not just strongly asks for tail call or error, but changes behavior.
To quote:
https://clang.llvm.org/docs/AttributeReference.html#musttail
"The lifetimes of all local variables and function parameters end 
immediately
before the call to the function.  This means that it is undefined behaviour
to pass a pointer or reference to a local variable to the called function,
which is not the case without the attribute.  Clang will emit a warning in
common cases where this happens."

The GCC behavior was just to error if we can't prove the musttail callee
could not have dereferenced escaped pointers to local vars or parameters
of the caller.  That is still the case for variables with non-trivial
destruction (even in clang), like vars with C++ non-trivial destructors or
variables with cleanup attribute.

The following patch changes the behavior to match that of clang, for all of
[[clang::musttail]], [[gnu::musttail]] and __attribute__((musttail)).

clang 20 actually added warning for some cases of it in
https://github.com/llvm/llvm-project/pull/109255
but it is under -Wreturn-stack-address warning.

Now, gcc doesn't have that warning, but -Wreturn-local-addr instead, and
IMHO it is better to have this under new warnings, because this isn't about
returning local address, but about passing it to a musttail call, or maybe
escaping to a musttail call.  And perhaps users will appreciate they can
control it separately as well.

The patch introduces 2 new warnings.
-Wmusttail-local-addr
which is turn on by default and warns for the always dumb cases of passing
an address of a local variable or parameter to musttail call's argument.
And then
-Wmaybe-musttail-local-addr
which is only diagnosed if -Wmusttail-local-addr was not diagnosed and
diagnoses at most one (so that we don't emit 100s of warnings for one call
if 100s of vars can escape) case where an address of a local var could have
escaped to the musttail call.  This is less severe, the code doesn't have
to be obviously wrong, so the warning is only enabled in -Wextra.

And I've adjusted also the documentation for this change and addition of
new warnings.

2025-04-02  Jakub Jelinek  

PR ipa/119376
* common.opt (Wmusttail-local-addr, Wmaybe-musttail-local-addr): 
New.
* tree-tailcall.cc (suitable_for_tail_call_opt_p): Don't fail for
TREE_ADDRESSABLE PARM_DECLs for musttail calls if diag_musttail.
Emit -Wmusttail-local-addr warnings.
(maybe_error_musttail): Use gimple_location instead of directly
accessing location member.
(find_tail_calls): For musttail calls if diag_musttail, don't fail
if address of local could escape to the call, instead emit
-Wmaybe-musttail-local-addr warnings.  Emit
-Wmaybe-musttail-local-addr warnings also for address taken
parameters.
* common.opt.urls: Regenerate.
* doc/extend.texi (musttail statement attribute): Clarify local
variables without non-trivial destruction are considered out of 
scope
before the tail call instruction.
* doc/invoke.texi (-Wno-musttail-local-addr,
-Wmaybe-musttail-local-addr): Document.

* c-c++-common/musttail8.c: Expect a warning rather than error in 
one
case.
(f4): Add int * argument.
* c-c++-common/musttail15.c: Don't disallow for C++98.
* c-c++-common/musttail16.c: Likewise.
* c-c++-common/musttail17.c: Likewise.
* c-c++-common/musttail18.c: Likewise.
* c-c++-common/musttail19.c: Likewise.  Expect a warning rather than
error in one case.
(f4): Add int * argument.
* c-c++-common/musttail20.c: Don't disallow for C++98.
* c-c++-common/musttail21.c: Likewise.
* c-c++-common/musttail28.c: New test.
* c-c++-common/musttail29.c: New test.
* c-c++-common/musttail30.c: New test.
* c-c++-common/musttail31.c: New test.
* g++.dg/ext/musttail1.C: New test.
* g++.dg/ext/musttail2.C: New test.
* g++.dg/ext/musttail3.C: New test.

Diff:
---
 gcc/common.opt  |   8 +++
 gcc/common.opt.urls |   6 ++
 gcc/doc/extend.texi |  49 --
 gcc/doc/invoke.texi |  52 

[gcc r14-11509] libstdc++: Fix -Wstringop-overread warning in std::vector [PR114758]

2025-04-02 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:f0c4ffcd86e50e7758f2408926bc880d3b810895

commit r14-11509-gf0c4ffcd86e50e7758f2408926bc880d3b810895
Author: Jonathan Wakely 
Date:   Fri Mar 28 15:41:41 2025 +

libstdc++: Fix -Wstringop-overread warning in std::vector [PR114758]

As in r13-4393-gcca06f0d6d76b0 and a few other commits, we can avoid
bogus warnings in std::vector by hoisting some loads to before the
allocation that calls operator new. This means that the compiler has
enough info to remove the dead branches that trigger bogus warnings.

On trunk this is only needed with -fno-assume-sane-operators-new-delete
but it will help on the branches where that option doesn't exist.

libstdc++-v3/ChangeLog:

PR libstdc++/114758
* include/bits/vector.tcc (vector::_M_fill_insert):
Hoist loads of begin() and end() before allocation.
* testsuite/23_containers/vector/bool/capacity/114758.cc: New
test.

Reviewed-by: Tomasz KamiƄski 

(cherry picked from commit 1f6c19f307c8de9830130a0ba071c24e3835beb3)

Diff:
---
 libstdc++-v3/include/bits/vector.tcc |  5 +++--
 .../testsuite/23_containers/vector/bool/capacity/114758.cc   | 12 
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index 200a75a19c3e..dafc2a31a8b4 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -1087,11 +1087,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
  const size_type __len = 
_M_check_len(__n, "vector::_M_fill_insert");
+ iterator __begin = begin(), __end = end();
  _Bit_pointer __q = this->_M_allocate(__len);
  iterator __start(std::__addressof(*__q), 0);
- iterator __i = _M_copy_aligned(begin(), __position, __start);
+ iterator __i = _M_copy_aligned(__begin, __position, __start);
  std::fill(__i, __i + difference_type(__n), __x);
- iterator __finish = std::copy(__position, end(),
+ iterator __finish = std::copy(__position, __end,
__i + difference_type(__n));
  this->_M_deallocate();
  this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/114758.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/114758.cc
new file mode 100644
index ..43efdef7e1d2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/114758.cc
@@ -0,0 +1,12 @@
+// { dg-options "-O3 -Werror=stringop-overread" }
+// { dg-do compile }
+
+// Bug libstdc++/114758 The layout of a std::vector reports a warning
+
+#include 
+
+void pr114758(std::vector& v)
+{
+  v.resize(3);
+  v = std::vector(3, false);
+}


[gcc r14-11512] libstdc++: Fix std::ranges::iter_move for function references [PR119469]

2025-04-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:88f0c1fe2825056f6d5fefa7809d878b109e7019

commit r14-11512-g88f0c1fe2825056f6d5fefa7809d878b109e7019
Author: Jonathan Wakely 
Date:   Wed Mar 26 11:21:32 2025 +

libstdc++: Fix std::ranges::iter_move for function references [PR119469]

The result of std::move (or a cast to an rvalue reference) on a function
reference is always an lvalue. Because std::ranges::iter_move was using
the type std::remove_reference_t&& as the result of std::move, it was
giving the wrong type for function references. Use a decltype-specifier
with declval>() instead of just using the
remove_reference_t&& type directly. This gives the right result,
while still avoiding the cost of doing overload resolution for
std::move.

libstdc++-v3/ChangeLog:

PR libstdc++/119469
* include/bits/iterator_concepts.h (_IterMove::__result): Use
decltype-specifier instead of an explicit type.
* testsuite/24_iterators/customization_points/iter_move.cc:
Check results for function references.

Reviewed-by: Tomasz KamiƄski 
(cherry picked from commit 3e52eb28c537aaa03afb78ef9dff8325c5f41f78)

Diff:
---
 libstdc++-v3/include/bits/iterator_concepts.h | 11 +--
 .../testsuite/24_iterators/customization_points/iter_move.cc  | 11 +++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/iterator_concepts.h 
b/libstdc++-v3/include/bits/iterator_concepts.h
index acd8e9d5ae11..f70a5d4e0609 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -128,12 +128,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  struct __result<_Tp>
  { using type = decltype(iter_move(std::declval<_Tp>())); };
 
-   // Otherwise, if *E if an lvalue, use std::move(*E).
+   // Otherwise, if *E is an lvalue, use std::move(*E).
template
  requires (!__adl_imove<_Tp>)
&& is_lvalue_reference_v<__iter_ref_t<_Tp>>
  struct __result<_Tp>
- { using type = remove_reference_t<__iter_ref_t<_Tp>>&&; };
+ {
+   // Instead of decltype(std::move(*E)) we define the type as the
+   // return type of std::move, i.e. remove_reference_t&&.
+   // N.B. the use of decltype(declval()) instead of just X&& is
+   // needed for function reference types, see PR libstdc++/119469.
+   using type
+ = decltype(std::declval>>());
+ };
 
template
  static constexpr bool
diff --git 
a/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc 
b/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc
index fbd7a481296b..f352a7ad05e4 100644
--- a/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc
+++ b/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc
@@ -157,9 +157,20 @@ test_pr106612()
   static_assert( std::same_as );
 }
 
+void
+test_pr119469()
+{
+  // rvalue references to function types are weird.
+  using F = int();
+  static_assert( std::same_as, F&> );
+  static_assert( std::same_as, F&> );
+  static_assert( std::same_as, F&> );
+}
+
 int
 main()
 {
   test01();
   test_adl();
+  test_pr119469();
 }


[gcc r14-11507] libstdc++: Fix -Warray-bounds warning in std::vector::resize [PR114945]

2025-04-02 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:6b11aed73f6601de32082a4519022d4de1ce8a8f

commit r14-11507-g6b11aed73f6601de32082a4519022d4de1ce8a8f
Author: Jonathan Wakely 
Date:   Mon Mar 31 12:30:44 2025 +0100

libstdc++: Fix -Warray-bounds warning in std::vector::resize [PR114945]

This is yet another false positive warning fix. This time the compiler
can't prove that when the vector has sufficient excess capacity to
append new elements, the pointer to the existing storage is not null.

libstdc++-v3/ChangeLog:

PR libstdc++/114945
* include/bits/vector.tcc (vector::_M_default_append): Add
unreachable condition so the compiler knows that _M_finish is
not null.
* testsuite/23_containers/vector/capacity/114945.cc: New test.

Reviewed-by: Tomasz KamiƄski 

(cherry picked from commit 844eed3364309bd20cbb7d6793a16b7c6b889ba4)

Diff:
---
 libstdc++-v3/include/bits/vector.tcc   |  3 ++
 .../23_containers/vector/capacity/114945.cc| 36 ++
 2 files changed, 39 insertions(+)

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index 0458d560075f..0bd1ae411028 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -816,6 +816,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
  if (__navail >= __n)
{
+ if (!this->_M_impl._M_finish)
+   __builtin_unreachable();
+
  _GLIBCXX_ASAN_ANNOTATE_GROW(__n);
  this->_M_impl._M_finish =
std::__uninitialized_default_n_a(this->_M_impl._M_finish,
diff --git a/libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc 
b/libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc
new file mode 100644
index ..daafc59d5a9d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc
@@ -0,0 +1,36 @@
+// { dg-options "-O2 -Werror=stringop-overflow -Werror=array-bounds" }
+// { dg-do compile { target c++11 } }
+
+// Bug libstdc++/114945
+// Sporadic std::vector::resize() -Wstringop-overflow or -Warray-bounds warning
+
+#include 
+#include 
+template  struct b {
+  void resize(std::size_t c) { d.resize(c); }
+  template  void f(a, e);
+  std::vector d;
+};
+#include 
+std::regex g;
+uint64_t h;
+uint32_t i;
+struct s {
+  enum class j : size_t;
+  void k();
+  using l = b;
+  std::vector m;
+};
+enum class s::j : size_t { n };
+void o() { g = ""; }
+void s::k() {
+  l p;
+  auto q = uint32_t(), r = uint32_t();
+  if (h)
+r = i;
+  b t;
+  if (q || r)
+p.f(j::n, 5);
+  t.resize(4);
+  m.push_back(p);
+}


[gcc r14-11510] libstdc++: Fix -Warray-bounds warning in std::vector [PR110498]

2025-04-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:9d5baaa92c6609191fd2488389562ac1ad1f0fb2

commit r14-11510-g9d5baaa92c6609191fd2488389562ac1ad1f0fb2
Author: Jonathan Wakely 
Date:   Fri Mar 28 15:41:41 2025 +

libstdc++: Fix -Warray-bounds warning in std::vector [PR110498]

In this case, we need to tell the compiler that the current size is not
larger than the new size so that all the existing elements can be copied
to the new storage. This avoids bogus warnings about overflowing the new
storage when the compiler can't tell that that cannot happen.

We might as well also hoist the loads of begin() and end() before the
allocation too. All callers will have loaded at least begin() before
calling _M_reallocate.

libstdc++-v3/ChangeLog:

PR libstdc++/110498
* include/bits/vector.tcc (vector::_M_reallocate):
Hoist loads of begin() and end() before allocation and use them
to state an unreachable condition.
* testsuite/23_containers/vector/bool/capacity/110498.cc: New
test.

Reviewed-by: Tomasz KamiƄski 

(cherry picked from commit aa3aaf2bfb8fcc17076993df4297597b68bc5f60)

Diff:
---
 libstdc++-v3/include/bits/vector.tcc   |  5 -
 .../23_containers/vector/bool/capacity/110498.cc   | 18 ++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index dafc2a31a8b4..c59c15beacd9 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -1059,9 +1059,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 vector::
 _M_reallocate(size_type __n)
 {
+  const iterator __begin = begin(), __end = end();
+  if (size_type(__end - __begin) > __n)
+   __builtin_unreachable();
   _Bit_pointer __q = this->_M_allocate(__n);
   iterator __start(std::__addressof(*__q), 0);
-  iterator __finish(_M_copy_aligned(begin(), end(), __start));
+  iterator __finish(_M_copy_aligned(__begin, __end, __start));
   this->_M_deallocate();
   this->_M_impl._M_start = __start;
   this->_M_impl._M_finish = __finish;
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc
new file mode 100644
index ..d2d09e10d19a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc
@@ -0,0 +1,18 @@
+// { dg-options "-O3 -Werror=array-bounds" }
+// { dg-do compile }
+
+// Bug libstdc++/110498
+// Spurious warnings stringop-overflow and array-bounds copying data as bytes
+// into vector::reserve
+
+#include 
+
+void f(std::vector& v)
+{
+  // Warning emitted when set to any number in the range [1,64].
+  const std::size_t reserve_size = 30;
+
+  v.reserve(reserve_size);
+  v.push_back(0);
+}
+


[gcc r14-11513] aarch64: Use PAUTH instead of V8_3A in some places

2025-04-02 Thread Alfie Richards via Gcc-cvs
https://gcc.gnu.org/g:35ed15af7ddab55c2ea1c07811f273a7c4e223fa

commit r14-11513-g35ed15af7ddab55c2ea1c07811f273a7c4e223fa
Author: Andrew Carlotti 
Date:   Tue Jul 30 16:26:04 2024 +0100

aarch64: Use PAUTH instead of V8_3A in some places

PR target/119383

gcc/ChangeLog:

* config/aarch64/aarch64.cc
(aarch64_expand_epilogue): Use TARGET_PAUTH.
* config/aarch64/aarch64.md: Update comment.

(cherry picked from commit 20385cb92cbd4a1934661ab97a162c1e25935836)

Diff:
---
 gcc/config/aarch64/aarch64.cc | 6 +++---
 gcc/config/aarch64/aarch64.md | 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0495adc7dd37..8f3a3735a97d 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9995,12 +9995,12 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall)
1) Sibcalls don't return in a normal way, so if we're about to call one
   we must authenticate.
 
-   2) The RETAA instruction is not available before ARMv8.3-A, so if we are
-  generating code for !TARGET_ARMV8_3 we can't use it and must
+   2) The RETAA instruction is not available without FEAT_PAuth, so if we
+  are generating code for !TARGET_PAUTH we can't use it and must
   explicitly authenticate.
 */
   if (aarch64_return_address_signing_enabled ()
-  && (sibcall || !TARGET_ARMV8_3))
+  && (sibcall || !TARGET_PAUTH))
 {
   switch (aarch64_ra_sign_key)
{
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index a08523a2b074..d3c381e82ce4 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7627,11 +7627,11 @@
   [(set_attr "type" "f_cvtf2i")]
 )
 
-;; Pointer authentication patterns are always provided.  In architecture
-;; revisions prior to ARMv8.3-A these HINT instructions operate as NOPs.
+;; Pointer authentication patterns are always provided.  On targets that
+;; don't implement FEAT_PAuth these HINT instructions operate as NOPs.
 ;; This lets the user write portable software which authenticates pointers
-;; when run on something which implements ARMv8.3-A, and which runs
-;; correctly, but does not authenticate pointers, where ARMv8.3-A is not
+;; when run on something which implements FEAT_PAuth, and which runs
+;; correctly, but does not authenticate pointers, where FEAT_PAuth is not
 ;; implemented.
 
 ;; Signing/Authenticating R30 using SP as the salt.


[gcc r15-9147] doc: Extend musttail attribute docs

2025-04-02 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:a3e790a9c9fbb84c103c1407d9afd4beae10d512

commit r15-9147-ga3e790a9c9fbb84c103c1407d9afd4beae10d512
Author: Jakub Jelinek 
Date:   Wed Apr 2 12:36:29 2025 +0200

doc: Extend musttail attribute docs

On Wed, Apr 02, 2025 at 10:32:20AM +0200, Richard Biener wrote:
> I wonder if we can amend the documentation to suggest to end lifetime
> of variables explicitly by proper scoping?

In the -Wmaybe-musttail-local-addr attribute description I've already
tried to show that in the example, but if you think something like
the following would make it clearer.

2025-04-02  Jakub Jelinek  

* doc/extend.texi (musttail statement attribute): Hint how
to avoid -Wmaybe-musttail-local-addr warnings.

Diff:
---
 gcc/doc/extend.texi | 25 +
 1 file changed, 25 insertions(+)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 9bf401b18a4d..109c7d26ea28 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -9368,6 +9368,31 @@ baz (int *x)
 @}
 @}
 @end smallexample
+
+To avoid the @option{-Wmaybe-musttail-local-addr} warning in the
+above @code{*x == 2} case and similar code, consider defining the
+maybe escaped variables in a separate scope which will end before the
+return statement if possible to make it clear that the variable is not
+live during the call.  So
+
+@smallexample
+  else if (*x == 2)
+@{
+  @{
+int a = 42;
+bar (&a);
+  @}
+  /* The call will be tail called (would not be without the
+ attribute), if bar stores the pointer anywhere, dereferencing
+ it in foo will be undefined behavior and there will be a warning
+ emitted for this with @option{-Wextra}, which implies
+ @option{-Wmaybe-musttail-local-addr}.  */
+  [[gnu::musttail]] return foo (nullptr);
+@}
+@end smallexample
+
+in this case.  That is not possible if it is function argument which
+is address taken because those are in scope for the whole function.
 @end table
 
 @node Attribute Syntax


[gcc(refs/users/jmelcr/heads/omp-cp)] omp-cp: Various bug fixes, mainly printing

2025-04-02 Thread Josef Melcr via Gcc-cvs
https://gcc.gnu.org/g:64b07469e7aa07f2534857ae44c2b6f03a311dba

commit 64b07469e7aa07f2534857ae44c2b6f03a311dba
Author: Josef Melcr 
Date:   Wed Apr 2 22:22:00 2025 +0200

omp-cp: Various bug fixes, mainly printing

gcc/ChangeLog:

* attr-callback.h (handle_callback_attribute): Minor bugfixes.

Signed-off-by: Josef Melcr 

Diff:
---
 gcc/attr-callback.h | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/gcc/attr-callback.h b/gcc/attr-callback.h
index cf22808c9b8b..63c54e753178 100644
--- a/gcc/attr-callback.h
+++ b/gcc/attr-callback.h
@@ -168,9 +168,24 @@ handle_callback_attribute (tree *node, tree name, tree 
args,
 }
   /* We have to use the function type for validation, as
  DECL_ARGUMENTS returns NULL at this point. */
-  unsigned callback_fn_idx = TREE_INT_CST_LOW (cb_fn_idx_node) - 1;
+  unsigned callback_fn_idx = TREE_INT_CST_LOW (cb_fn_idx_node);
   tree decl_type_args = TYPE_ARG_TYPES (TREE_TYPE (decl));
+  tree it;
   unsigned decl_nargs = list_length (decl_type_args);
+  for (it = decl_type_args; it != NULL_TREE; it = TREE_CHAIN (it))
+if (it == void_list_node)
+  {
+   --decl_nargs;
+   break;
+  }
+  if (callback_fn_idx == CB_UNKNOWN_POS)
+{
+  error_at (DECL_SOURCE_LOCATION (decl),
+   "callback function position cannot be marked as unknown");
+  *no_add_attrs = true;
+  return NULL_TREE;
+}
+  --callback_fn_idx;
   if (callback_fn_idx >= decl_nargs)
 {
   error_at (DECL_SOURCE_LOCATION (decl),
@@ -195,12 +210,11 @@ handle_callback_attribute (tree *node, tree name, tree 
args,
 {
   error_at (DECL_SOURCE_LOCATION (decl),
"argument no. %d is not an address of a function",
-   callback_fn_idx);
+   callback_fn_idx + 1);
   *no_add_attrs = true;
   return NULL_TREE;
 }
 
-  tree it;
   tree type_args = TYPE_ARG_TYPES (cfn_pointee_type);
   /* Compare the length of the list of argument indices
  and the real number of parameters the callback takes. */
@@ -268,7 +282,7 @@ handle_callback_attribute (tree *node, tree name, tree args,
  error_at (DECL_SOURCE_LOCATION (decl),
"argument type at index %d is not compatible with callback "
"argument type at index %d",
-   curr, arg_idx);
+   arg_idx + 1, curr + 1);
  *no_add_attrs = true;
  continue;
}


[gcc(refs/users/jmelcr/heads/omp-cp)] omp-cp: Add testcases for omp-cp and callback attribute.

2025-04-02 Thread Josef Melcr via Gcc-cvs
https://gcc.gnu.org/g:b1fabc31774a8917426c9bdae59da45417d3c052

commit b1fabc31774a8917426c9bdae59da45417d3c052
Author: Josef Melcr 
Date:   Wed Apr 2 22:23:10 2025 +0200

omp-cp: Add testcases for omp-cp and callback attribute.

gcc/testsuite/ChangeLog:

* gcc.dg/attr-callback.c: New test.
* gcc.dg/ipa/ipcp-cb1.c: New test.
* gcc.dg/ipa/ipcp-cb2.c: New test.

Signed-off-by: Josef Melcr 

Diff:
---
 gcc/testsuite/gcc.dg/attr-callback.c | 79 
 gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c  | 25 
 gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c  | 53 
 3 files changed, 157 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/attr-callback.c 
b/gcc/testsuite/gcc.dg/attr-callback.c
new file mode 100644
index ..def371193f59
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-callback.c
@@ -0,0 +1,79 @@
+/* Test callback attribute error checking. */
+
+/* { dg-do compile } */
+
+void 
+__attribute__((callback(1, 2)))
+correct_1(void (*)(int*), int*);
+
+void 
+__attribute__((callback(1, 2, 3)))
+correct_2(void (*)(int*, double*), int*, double*);
+
+void 
+__attribute__((callback(1, 0)))
+unknown_1(void (*)(int*));
+
+void 
+__attribute__((callback(1, 2, 0)))
+unknown_2(void (*)(int*, double*), int*, double*, char*);
+
+void 
+__attribute__((callback(1, 0, 3, 3)))
+too_many(void (*)(int*, double*), int*, double*); /* { dg-error "argument 
number mismatch, 2 expected, got 3" }*/
+
+void 
+__attribute__((callback(1, 2)))
+too_few_1(void (*)(int*, double*), int*, double*); /* { dg-error "argument 
number mismatch, 2 expected, got 1" }*/
+
+void 
+__attribute__((callback(1)))
+too_few_2(void (*)(int*, double*), int*, double*); /* { dg-error "argument 
number mismatch, 2 expected, got 0" }*/
+
+void 
+__attribute__((callback(3, 1)))
+promotion(char*, float, int (*)(int*));
+
+void 
+__attribute__((callback(2, 3)))
+downcast(char*, void* (*)(float*), double*);
+
+void 
+__attribute__((callback(1, 2, 5)))
+out_of_range_1(char (*)(float*, double*), float*, double*, int*); /* { 
dg-error "callback argument index 5 is out of range" } */
+
+void 
+__attribute__((callback(1, -2, 3)))
+out_of_range_2(char (*)(float*, double*), float*, double*, int*); /* { 
dg-error "callback argument index -2 is out of range" } */
+
+void 
+__attribute__((callback(-1, 2, 3)))
+out_of_range_3(char (*)(float*, double*), float*, double*, int*); /* { 
dg-error "callback function position out of range" } */
+
+void 
+__attribute__((callback(0, 2, 3)))
+unknown_fn(char (*)(float*, double*), float*, double*, int*); /* { dg-error 
"callback function position cannot be marked as unknown" } */
+
+void
+__attribute__((callback(1, 2)))
+not_a_fn(int, int); /* { dg-error "argument no. 1 is not an address of a 
function" } */
+
+struct S{
+  int x;
+};
+
+void
+__attribute__((callback(1, 2)))
+incompatible_types_1(void (*)(struct S*), struct S); /* { dg-error "argument 
type at index 2 is not compatible with callback argument type at index 1" } */
+
+void
+__attribute__((callback(1, 3, 2)))
+incompatible_types_2(void (*)(struct S*, int*), int*, double); /* { dg-error 
"argument type at index 3 is not compatible with callback argument type at 
index 1" } */
+
+void
+__attribute__((callback(1, "2")))
+wrong_arg_type_1(void (*)(void*), void*); /* { dg-error "argument no. 1 is not 
an integer constant" } */
+
+void
+__attribute__((callback("not a number", 2, 2)))
+wrong_arg_type_2(void (*)(void*, void*), void*); /* { dg-error "argument 
specifying callback function position is not an integer constant" } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c 
b/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c
new file mode 100644
index ..5f672a506f46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c
@@ -0,0 +1,25 @@
+/* Test that we can propagate constants into outlined OpenMP kernels. 
+   This tests the underlying callback attribute and its related edges. */
+
+/* { dg-do run } */
+/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */
+/* { dg-require-effective-target fopenmp } */
+/* { dg-require-effective-target lto } */
+
+int a[100];
+void test(int c) {
+#pragma omp parallel for
+  for (int i = 0; i < c; i++) {
+if (!__builtin_constant_p(c)) {
+  __builtin_abort();
+}
+a[i] = i;
+  }
+}
+int main() {
+  test(100);
+  return a[5] - 5;
+}
+
+/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of 
test._omp_fn" "cp" } } */
+/* { dg-final { scan-wpa-ipa-dump "Aggregate replacements: 
0\\\[0]=100\\(by_ref\\)" "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c 
b/gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c
new file mode 100644
index ..b42c2a09d8bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cb2.c
@@ -0,0 +1,53 @@
+/* Test that we can handle multiple callback attributes and use them to
+   propagate into callbacks. 'cb1' body borrowed from a ipa-cp test to get the
+   pass to work. *

[gcc r13-9489] libstdc++: Do not use compiler built-in in requires-clause

2025-04-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:5f14b91fbebfa880a4001aff153ed78f26f366a7

commit r13-9489-g5f14b91fbebfa880a4001aff153ed78f26f366a7
Author: Jonathan Wakely 
Date:   Wed Apr 2 12:52:54 2025 +0100

libstdc++: Do not use compiler built-in in requires-clause

This is a partial backport of r14-6064-gc3f281a0c1ca50 which replaced a
use of __is_trivially_copyable in the requires-clause for std::bit_cast.
The change isn't actually necessary on the gcc-13 and gcc-12 branches,
but in gcc-14 using the built-in directly because ill-formed because we
started to mangle requires-clauses.

Replacing the built-in with the equivalent library trait makes it easier
to do bisections with preprocessed source created by GCC 13, because the
built-in won't cause errors with gcc-14 and later.

libstdc++-v3/ChangeLog:

* include/std/bit (bit_cast): Use library trait instead of
__is_trivially_copyable built-in.

Diff:
---
 libstdc++-v3/include/std/bit | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index 5eb40218be9d..03a2938b493b 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -81,7 +81,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 bit_cast(const _From& __from) noexcept
 #ifdef __cpp_concepts
 requires (sizeof(_To) == sizeof(_From))
-  && __is_trivially_copyable(_To) && __is_trivially_copyable(_From)
+  && is_trivially_copyable_v<_To> && is_trivially_copyable_v<_From>
 #endif
 {
   return __builtin_bit_cast(_To, __from);


[gcc r15-9154] tailc: Deal with trivially useless EH cleanups [PR119491]

2025-04-02 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:8ea537988f718f026d94b558e09479c3b5fe088a

commit r15-9154-g8ea537988f718f026d94b558e09479c3b5fe088a
Author: Jakub Jelinek 
Date:   Wed Apr 2 20:02:34 2025 +0200

tailc: Deal with trivially useless EH cleanups [PR119491]

The following testcases FAIL, because EH cleanup is performed only before
IPA and then right before musttail pass.
At -O2 etc. (except for -O0/-Og) we handle musttail calls in the tailc
pass though, and we can fail at that point because the calls might appear
to throw internal exceptions which just don't do anything interesting
(perhaps have debug statements or clobber statements in them) before they
continue with resume of the exception (i.e. throw it externally).

As Richi said in the PR (and I agree) that moving passes is risky at this
point, the following patch instead teaches the tail{r,c} and musttail
passes to deal with such extra EDGE_EH edges.

It is fairly simple thing, if we see an EDGE_EH edge from the call we
just look up where it lands and if there are no
non-debug/non-clobber/non-label statements before resx which throws
externally, such edge can be ignored for tail call optimization or
tail recursion.  At other spots I just need to avoid using
single_succ/single_succ_edge because the bb might have another edge -
EDGE_EH.

To make this less risky, this is done solely for the musttail calls for now.

2025-04-02  Jakub Jelinek  

PR tree-optimization/119491
* tree-tailcall.cc (single_non_eh_succ_edge): New function.
(independent_of_stmt_p): Use single_non_eh_succ_edge (bb)->dest
instead of single_succ (bb).
(empty_eh_cleanup): New function.
(find_tail_calls): Diagnose throwing of exceptions which do not
propagate only if there are no EDGE_EH successor edges.  If there 
are
and the call is musttail, use empty_eh_cleanup to find if the 
cleanup
is not empty.  If not or the call is not musttail, use different
diagnostics.  Set is_noreturn even if there are successor edges.  
Use
single_non_eh_succ_edge (abb) instead of single_succ_edge (abb).  
Punt
on internal noreturn calls.
(decrease_profile): Don't assert 0 or 1 successor edges.
(eliminate_tail_call): Use
single_non_eh_succ_edge (gsi_bb (t->call_gsi)) instead of
single_succ_edge (gsi_bb (t->call_gsi)).
(tree_optimize_tail_calls_1): Also look into basic blocks with
single succ edge which is EDGE_EH for noreturn musttail calls.

* g++.dg/opt/musttail3.C: New test.
* g++.dg/opt/musttail4.C: New test.
* g++.dg/opt/musttail5.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/opt/musttail3.C |  41 +
 gcc/testsuite/g++.dg/opt/musttail4.C |  35 +++
 gcc/testsuite/g++.dg/opt/musttail5.C |  41 +
 gcc/tree-tailcall.cc | 113 ---
 4 files changed, 207 insertions(+), 23 deletions(-)

diff --git a/gcc/testsuite/g++.dg/opt/musttail3.C 
b/gcc/testsuite/g++.dg/opt/musttail3.C
new file mode 100644
index ..1c4e54952b1e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/musttail3.C
@@ -0,0 +1,41 @@
+// PR tree-optimization/119491
+// { dg-do compile { target { external_musttail && c++11 } } }
+// { dg-options "-O2" }
+
+struct A {
+  struct B {};
+  A () {}
+};
+void qux ();
+unsigned char v;
+A w;
+void foo (A);
+
+template 
+[[gnu::always_inline]] static inline void
+bar (int &)
+{
+}
+
+[[gnu::always_inline]] static inline void
+baz (int *)
+{
+  int r = 0;
+  bar (r);
+}
+
+[[gnu::always_inline]] inline void
+corge (A)
+{
+  if (v)
+qux ();
+  [[gnu::musttail]] return foo (w);
+}
+
+void
+freddy (A)
+{
+  int t;
+  baz (&t);
+  [[gnu::musttail]] return corge (A{});
+}
diff --git a/gcc/testsuite/g++.dg/opt/musttail4.C 
b/gcc/testsuite/g++.dg/opt/musttail4.C
new file mode 100644
index ..ede2959f7d74
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/musttail4.C
@@ -0,0 +1,35 @@
+// { dg-do compile { target { external_musttail && c++11 } } }
+// { dg-options "-O2 -fexceptions" }
+
+struct S { ~S (); };
+volatile int v;
+struct T { ~T () { v = v + 1; } };
+struct U { ~U () {} };
+int foo ();
+
+int
+bar () noexcept
+{
+  [[gnu::musttail]] return foo (); // { dg-error "cannot tail-call: call 
may throw exception that does not propagate" }
+}
+
+int
+baz ()
+{
+  S s;
+  [[gnu::musttail]] return foo (); // { dg-error "cannot tail-call: other 
reasons" }
+}
+
+int
+qux ()
+{
+  T t;
+  [[gnu::musttail]] return foo (); // { dg-error "cannot tail-call: other 
reasons" }
+}
+
+int
+corge ()
+{
+  U u;
+  [[gnu::musttail]] return foo ();
+}
diff --git a/gcc/testsuite/g++.dg/opt/musttail5.C 
b/gcc/testsuite/g++.dg/opt/musttail5.C
new file mode 100644
index ..604dd690

[gcc/devel/rust/master] Resolve module final self segment in use decls

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:9c4e2a7814fcf8889258e028a4c0d4cdc960f6b9

commit 9c4e2a7814fcf8889258e028a4c0d4cdc960f6b9
Author: Pierre-Emmanuel Patry 
Date:   Mon Mar 24 18:31:12 2025 +0100

Resolve module final self segment in use decls

Lowercase self suffix with path was not resolved properly, this should
point to the module right before.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Add a new specialized function
to retrieve the last "real" segment depending on the namespace.
* resolve/rust-forever-stack.h: Add new function prototype.
* resolve/rust-early-name-resolver-2.0.cc 
(Early::finalize_rebind_import):
Set declared name according to the selected segment, if there is a 
self
suffix in the use declaration then select the previous segment.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 17 ++
 gcc/rust/resolve/rust-forever-stack.h|  4 
 gcc/rust/resolve/rust-forever-stack.hxx  | 29 
 3 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index b4808e2508ba..d5f85b7d16ce 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -417,10 +417,19 @@ Early::finalize_rebind_import (const Early::ImportPair 
&mapping)
   declared_name = rebind.get_identifier ().as_string ();
   locus = rebind.get_identifier ().get_locus ();
   break;
-case AST::UseTreeRebind::NewBindType::NONE:
-  declared_name = path.get_final_segment ().as_string ();
-  locus = path.get_final_segment ().get_locus ();
-  break;
+  case AST::UseTreeRebind::NewBindType::NONE: {
+   const auto &segments = path.get_segments ();
+   // We don't want to insert `self` with `use module::self`
+   if (path.get_final_segment ().is_lower_self_seg ())
+ {
+   rust_assert (segments.size () > 1);
+   declared_name = segments[segments.size () - 2].as_string ();
+ }
+   else
+ declared_name = path.get_final_segment ().as_string ();
+   locus = path.get_final_segment ().get_locus ();
+   break;
+  }
 case AST::UseTreeRebind::NewBindType::WILDCARD:
   rust_unreachable ();
   break;
diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 95e1eead2757..946aef2fb48b 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -795,6 +795,10 @@ private:
 SegIterator iterator,
 std::function insert_segment_resolution);
 
+  tl::optional resolve_final_segment (Node &final_node,
+  std::string &seg_name,
+  bool is_lower_self);
+
   /* Helper functions for forward resolution (to_canonical_path, to_rib...) */
   struct DfsResult
   {
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 44318d1b298f..f96a1d775d66 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -594,6 +594,26 @@ ForeverStack::resolve_segments (
   return *current_node;
 }
 
+template <>
+inline tl::optional
+ForeverStack::resolve_final_segment (Node &final_node,
+  std::string &seg_name,
+  bool is_lower_self)
+{
+  if (is_lower_self)
+return Rib::Definition::NonShadowable (final_node.id);
+  else
+return final_node.rib.get (seg_name);
+}
+
+template 
+tl::optional
+ForeverStack::resolve_final_segment (Node &final_node, std::string 
&seg_name,
+   bool is_lower_self)
+{
+  return final_node.rib.get (seg_name);
+}
+
 template 
 template 
 tl::optional
@@ -643,12 +663,13 @@ ForeverStack::resolve_path (
   if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
return tl::nullopt;
 
-  std::string seg_name
-   = unwrap_type_segment (segments.back ()).as_string ();
+  auto &seg = unwrap_type_segment (segments.back ());
+  std::string seg_name = seg.as_string ();
 
   // assuming this can't be a lang item segment
-  tl::optional res = final_node.rib.get (seg_name);
-
+  tl::optional res
+   = resolve_final_segment (final_node, seg_name,
+seg.is_lower_self_seg ());
   // Ok we didn't find it in the rib, Lets try the prelude...
   if (!res)
res = get_prelude (seg_name);


[gcc/devel/rust/master] Add new test to highlight namespace for self import

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:ce8e35fc28ccc9ade61ff9c83fee55e2673acce8

commit ce8e35fc28ccc9ade61ff9c83fee55e2673acce8
Author: Pierre-Emmanuel Patry 
Date:   Tue Mar 25 19:03:00 2025 +0100

Add new test to highlight namespace for self import

gcc/testsuite/ChangeLog:

* rust/compile/self_import_namespace.rs: New test.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/testsuite/rust/compile/self_import_namespace.rs | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/gcc/testsuite/rust/compile/self_import_namespace.rs 
b/gcc/testsuite/rust/compile/self_import_namespace.rs
new file mode 100644
index ..2d9b2ed8e0fc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self_import_namespace.rs
@@ -0,0 +1,14 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+
+mod bar {
+pub mod foo {}
+pub fn foo() {}
+}
+
+// This only imports the module `foo`. The function `foo` lives in
+// the value namespace and is not imported.
+use bar::foo::{self};
+
+fn main() {
+foo(); // { dg-error "expected value" }
+}


[gcc/devel/rust/master] gccrs: Give the builtin unit struct an actual locus

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:29cace33c167fd22cf91f3f2f982e70f082db69f

commit 29cace33c167fd22cf91f3f2f982e70f082db69f
Author: Philip Herron 
Date:   Thu Mar 27 15:15:08 2025 +

gccrs: Give the builtin unit struct an actual locus

This has been a pet peeve of mine for a while because the gimple never
emitted the struct () name properly it was always empty which for record
types they always require a real locus or they dont get a proper name.

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc (HIRCompileBase::unit_expression): 
pass ctx
* backend/rust-compile-base.h: cant be static
* backend/rust-compile-intrinsic.cc (try_handler_inner): pass ctx
* backend/rust-compile-type.cc
(TyTyResolveCompile::get_unit_type): update to grab the first locus
(TyTyResolveCompile::visit): pass ctx
* backend/rust-compile-type.h: likewise

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/backend/rust-compile-base.cc  |  2 +-
 gcc/rust/backend/rust-compile-base.h   |  2 +-
 gcc/rust/backend/rust-compile-intrinsic.cc |  2 +-
 gcc/rust/backend/rust-compile-type.cc  | 17 +
 gcc/rust/backend/rust-compile-type.h   |  2 +-
 5 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index c71417da41eb..d8a71f5d7eb6 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -1023,7 +1023,7 @@ HIRCompileBase::resolve_method_address (TyTy::FnType 
*fntype,
 tree
 HIRCompileBase::unit_expression (location_t locus)
 {
-  tree unit_type = TyTyResolveCompile::get_unit_type ();
+  tree unit_type = TyTyResolveCompile::get_unit_type (ctx);
   return Backend::constructor_expression (unit_type, false, {}, -1, locus);
 }
 
diff --git a/gcc/rust/backend/rust-compile-base.h 
b/gcc/rust/backend/rust-compile-base.h
index 4d55407ca3b9..323b1a025226 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -110,7 +110,7 @@ protected:
 const Resolver::CanonicalPath &canonical_path,
 TyTy::FnType *fntype);
 
-  static tree unit_expression (location_t locus);
+  tree unit_expression (location_t locus);
 
   void setup_fndecl (tree fndecl, bool is_main_entry_point, bool is_generic_fn,
 HIR::Visibility &visibility,
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 31c5d49b0ab2..cd79a7bd0b9a 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -1322,7 +1322,7 @@ try_handler_inner (Context *ctx, TyTy::FnType *fntype, 
bool is_new_api)
 
   if (is_new_api)
 {
-  auto ret_type = TyTyResolveCompile::get_unit_type ();
+  auto ret_type = TyTyResolveCompile::get_unit_type (ctx);
   auto ret_expr = Backend::constructor_expression (ret_type, false, {}, -1,
   UNDEF_LOCATION);
   normal_return_stmt
diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index 58a0d9aaf586..0ab9e420b5dd 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -81,13 +81,22 @@ TyTyResolveCompile::get_implicit_enumeral_node_type 
(TyTy::BaseType *repr)
 }
 
 tree
-TyTyResolveCompile::get_unit_type ()
+TyTyResolveCompile::get_unit_type (Context *ctx)
 {
   static tree unit_type;
   if (unit_type == nullptr)
 {
+  auto cn = ctx->get_mappings ().get_current_crate ();
+  auto &c = ctx->get_mappings ().get_ast_crate (cn);
+  location_t locus = BUILTINS_LOCATION;
+  if (c.items.size () > 0)
+   {
+ auto &item = c.items[0];
+ locus = item->get_locus ();
+   }
+
   auto unit_type_node = Backend::struct_type ({});
-  unit_type = Backend::named_type ("()", unit_type_node, 
BUILTINS_LOCATION);
+  unit_type = Backend::named_type ("()", unit_type_node, locus);
 }
   return unit_type;
 }
@@ -421,7 +430,7 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type)
 {
   if (type.num_fields () == 0)
 {
-  translated = get_unit_type ();
+  translated = get_unit_type (ctx);
   return;
 }
 
@@ -724,7 +733,7 @@ TyTyResolveCompile::visit (const TyTy::StrType &type)
 void
 TyTyResolveCompile::visit (const TyTy::NeverType &)
 {
-  translated = get_unit_type ();
+  translated = get_unit_type (ctx);
 }
 
 void
diff --git a/gcc/rust/backend/rust-compile-type.h 
b/gcc/rust/backend/rust-compile-type.h
index b8976e97ac53..aa20067fc477 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -30,7 +30,7 @@ public:
   static tree compile (Context *ctx, const TyTy::BaseType *ty,
   bool trait_object_mode = false);
 
-  static tree get_unit_type ();

[gcc/devel/rust/master] gccrs: Fix ICE when compiling path which resolves to trait constant

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:08bfb3550e76b14d6cb6e6eb1478bff79bacf091

commit 08bfb3550e76b14d6cb6e6eb1478bff79bacf091
Author: Philip Herron 
Date:   Thu Mar 27 16:32:21 2025 +

gccrs: Fix ICE when compiling path which resolves to trait constant

Fixes Rust-GCC#3552

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc 
(HIRCompileBase::query_compile): check for Expr trait
* hir/rust-hir-dump.cc (Dump::visit): expr is optional

gcc/testsuite/ChangeLog:

* rust/compile/issue-3552.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 21 +
 gcc/rust/hir/rust-hir-dump.cc |  4 +++-
 gcc/testsuite/rust/compile/issue-3552.rs  | 14 ++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index 9423951962f1..d4901a44bead 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -301,6 +301,27 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType 
*lookup,
trait->get_mappings ().get_defid (), &trait_ref);
  rust_assert (ok);
 
+ if (trait_item.value ()->get_item_kind ()
+ == HIR::TraitItem::TraitItemKind::CONST)
+   {
+ auto &c
+   = *static_cast (trait_item.value ());
+ if (!c.has_expr ())
+   {
+ rich_location r (line_table, expr_locus);
+ r.add_range (trait->get_locus ());
+ r.add_range (c.get_locus ());
+ rust_error_at (r, "no default expression on trait constant");
+ return error_mark_node;
+   }
+
+ return CompileExpr::Compile (c.get_expr (), ctx);
+   }
+
+ if (trait_item.value ()->get_item_kind ()
+ != HIR::TraitItem::TraitItemKind::FUNC)
+   return error_mark_node;
+
  // the type resolver can only resolve type bounds to their trait
  // item so its up to us to figure out if this path should resolve
  // to an trait-impl-block-item or if it can be defaulted to the
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 13ad7fa6ab32..983922c73e31 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1932,7 +1932,9 @@ Dump::visit (TraitItemConst &e)
 
   put_field ("name", e.get_name ().as_string ());
   visit_field ("type", e.get_type ());
-  visit_field ("expr", e.get_expr ());
+  if (e.has_expr ())
+visit_field ("expr", e.get_expr ());
+
   end ("TraitItemConst");
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-3552.rs 
b/gcc/testsuite/rust/compile/issue-3552.rs
new file mode 100644
index ..9a4451b14b89
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3552.rs
@@ -0,0 +1,14 @@
+trait Foo {
+const BAR: u32;
+}
+
+const TRAIT_REF_BAR: u32 = ::BAR;
+// { dg-error "no default expression on trait constant" "" { target *-*-* } 
.-1 }
+
+struct GlobalTraitRef;
+
+impl Foo for GlobalTraitRef {
+const BAR: u32 = TRAIT_REF_BAR;
+}
+
+fn main() {}


[gcc/devel/rust/master] nr2.0: Rename prelude to lang_prelude

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:d60a925642b5c485c26f7a8a3e5eaec988e007e2

commit d60a925642b5c485c26f7a8a3e5eaec988e007e2
Author: Owen Avery 
Date:   Thu Mar 27 15:30:23 2025 -0400

nr2.0: Rename prelude to lang_prelude

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::get_prelude): Rename to...
(ForeverStack::get_lang_prelude): ...here.
(ForeverStack::prelude): Rename to...
(ForeverStack::lang_prelude): ...here.
(ForeverStack::ForeverStack): Handle renames.
* resolve/rust-forever-stack.hxx
(ForeverStack::push_inner): Likewise.
(ForeverStack::resolve_segments): Likewise.
(ForeverStack::resolve_path): Likewise.
(ForeverStack::get_prelude): Rename to...
(ForeverStack::get_lang_prelude): ...here and handle renames.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Handle renames.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/resolve/rust-forever-stack.h   |  8 
 gcc/rust/resolve/rust-forever-stack.hxx | 17 +
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc |  2 +-
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 946aef2fb48b..0f6ad956f2fa 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -548,7 +548,7 @@ template  class ForeverStack
 public:
   ForeverStack ()
 : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
-  prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
+  lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
   cursor_reference (root)
   {
 rust_assert (root.is_root ());
@@ -658,8 +658,8 @@ public:
* the current map, an empty one otherwise.
*/
   tl::optional get (const Identifier &name);
-  tl::optional get_prelude (const Identifier &name);
-  tl::optional get_prelude (const std::string &name);
+  tl::optional get_lang_prelude (const Identifier &name);
+  tl::optional get_lang_prelude (const std::string &name);
 
   /**
* Resolve a path to its definition in the current `ForeverStack`
@@ -767,7 +767,7 @@ private:
* It has the root node as a parent, and acts as a "special case" for name
* resolution
*/
-  Node prelude;
+  Node lang_prelude;
 
   std::reference_wrapper cursor_reference;
 
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index f96a1d775d66..a8b8f98ca041 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -77,7 +77,7 @@ ForeverStack::push_inner (Rib rib, Link link)
   rust_assert (&cursor_reference.get () == &root);
   // Prelude doesn't have an access path
   rust_assert (!link.path);
-  update_cursor (this->prelude);
+  update_cursor (this->lang_prelude);
   return;
 }
   // If the link does not exist, we create it and emplace a new `Node` with the
@@ -319,16 +319,16 @@ ForeverStack::get (const Identifier &name)
 
 template 
 tl::optional
-ForeverStack::get_prelude (const Identifier &name)
+ForeverStack::get_lang_prelude (const Identifier &name)
 {
-  return prelude.rib.get (name.as_string ());
+  return lang_prelude.rib.get (name.as_string ());
 }
 
 template 
 tl::optional
-ForeverStack::get_prelude (const std::string &name)
+ForeverStack::get_lang_prelude (const std::string &name)
 {
-  return prelude.rib.get (name);
+  return lang_prelude.rib.get (name);
 }
 
 template <>
@@ -571,7 +571,7 @@ ForeverStack::resolve_segments (
  if (current_node->is_root () && !searched_prelude)
{
  searched_prelude = true;
- current_node = &prelude;
+ current_node = &lang_prelude;
  continue;
}
 
@@ -641,7 +641,8 @@ ForeverStack::resolve_path (
= get (unwrap_type_segment (segments.back ()).as_string ());
 
   if (!res)
-   res = get_prelude (unwrap_type_segment (segments.back ()).as_string ());
+   res = get_lang_prelude (
+ unwrap_type_segment (segments.back ()).as_string ());
 
   if (res && !res->is_ambiguous ())
insert_segment_resolution (segments.back (), res->get_node_id ());
@@ -672,7 +673,7 @@ ForeverStack::resolve_path (
 seg.is_lower_self_seg ());
   // Ok we didn't find it in the rib, Lets try the prelude...
   if (!res)
-   res = get_prelude (seg_name);
+   res = get_lang_prelude (seg_name);
 
   if (res && !res->is_ambiguous ())
insert_segment_resolution (segments.back (), res->get_node_id ());
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 5fcf0ec27cde..d68582667f3a 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/reso

[gcc/devel/rust/master] gccrs: FIX ICE when working with HIR::BareFunctionType

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:8d1c01c818428a432dc7a64237bdf62aa3fd0c6c

commit 8d1c01c818428a432dc7a64237bdf62aa3fd0c6c
Author: Philip Herron 
Date:   Fri Mar 28 17:42:07 2025 +

gccrs: FIX ICE when working with HIR::BareFunctionType

Fixes Rust-GCC#3615

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): check has type
* hir/tree/rust-hir-type.cc (BareFunctionType::BareFunctionType): 
likewise

gcc/testsuite/ChangeLog:

* rust/compile/issue-3615.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/hir/rust-hir-dump.cc| 4 +++-
 gcc/rust/hir/tree/rust-hir-type.cc   | 3 ++-
 gcc/testsuite/rust/compile/issue-3615.rs | 7 +++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 983922c73e31..b6dcf184ae4e 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -2440,7 +2440,9 @@ Dump::visit (BareFunctionType &e)
   end_field ("params");
 }
 
-  visit_field ("return_type", e.get_return_type ());
+  if (e.has_return_type ())
+visit_field ("return_type", e.get_return_type ());
+
   put_field ("is_variadic", std::to_string (e.get_is_variadic ()));
   end ("BareFunctionType");
 }
diff --git a/gcc/rust/hir/tree/rust-hir-type.cc 
b/gcc/rust/hir/tree/rust-hir-type.cc
index 689d86b7372b..6a6c319fc98e 100644
--- a/gcc/rust/hir/tree/rust-hir-type.cc
+++ b/gcc/rust/hir/tree/rust-hir-type.cc
@@ -268,7 +268,8 @@ BareFunctionType::BareFunctionType (BareFunctionType const 
&other)
 for_lifetimes (other.for_lifetimes),
 function_qualifiers (other.function_qualifiers), params (other.params),
 is_variadic (other.is_variadic),
-return_type (other.return_type->clone_type ())
+return_type (other.has_return_type () ? other.return_type->clone_type ()
+ : nullptr)
 {}
 
 BareFunctionType &
diff --git a/gcc/testsuite/rust/compile/issue-3615.rs 
b/gcc/testsuite/rust/compile/issue-3615.rs
new file mode 100644
index ..e5c50725ea2b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3615.rs
@@ -0,0 +1,7 @@
+pub trait Trait {
+pub fn nrvo(init: fn()) -> [u8; 4096] {
+let mut buf = [0; 4096];
+
+buf
+}
+}


[gcc/devel/rust/master] gccrs: FIX ICE for malformed repr attribute

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:6130523c8b98178e6bdbde9e33a4ca8c95226bf1

commit 6130523c8b98178e6bdbde9e33a4ca8c95226bf1
Author: Philip Herron 
Date:   Fri Mar 28 17:52:51 2025 +

gccrs: FIX ICE for malformed repr attribute

Fixes Rust-GCC#3614

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.cc 
(TypeCheckBase::parse_repr_options): check for input

gcc/testsuite/ChangeLog:

* rust/compile/issue-3614.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-base.cc | 6 ++
 gcc/testsuite/rust/compile/issue-3614.rs   | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index b6d2f035ad44..f60b540cd8c1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -305,6 +305,12 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
   for (const auto &attr : attrs)
 {
   bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
+  if (is_repr && !attr.has_attr_input ())
+   {
+ rust_error_at (attr.get_locus (), "malformed %qs attribute", "repr");
+ continue;
+   }
+
   if (is_repr)
{
  const AST::AttrInput &input = attr.get_attr_input ();
diff --git a/gcc/testsuite/rust/compile/issue-3614.rs 
b/gcc/testsuite/rust/compile/issue-3614.rs
new file mode 100644
index ..350a7e43ba8e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3614.rs
@@ -0,0 +1,3 @@
+#[repr] // { dg-error "malformed .repr. attribute" }
+
+struct _B {}


[gcc/devel/rust/master] gccrs: fix ice when setting up regions

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:8b5f1f296b60f9343ed995f14552d022f077e1f6

commit 8b5f1f296b60f9343ed995f14552d022f077e1f6
Author: Philip Herron 
Date:   Fri Mar 28 18:24:57 2025 +

gccrs: fix ice when setting up regions

num regions is based on the used arguments of regions which can be
less than the substutions requirements. So lets check for that and allow
anon regions to be created for them.

Fixes Rust-GCC#3605

gcc/rust/ChangeLog:

* typecheck/rust-tyty-subst.h: check for min range

gcc/testsuite/ChangeLog:

* rust/compile/issue-3605.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/typecheck/rust-tyty-subst.h | 2 +-
 gcc/testsuite/rust/compile/issue-3605.rs | 5 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/typecheck/rust-tyty-subst.h 
b/gcc/rust/typecheck/rust-tyty-subst.h
index 86bc08bb843f..65d5d5a8ff16 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -125,7 +125,7 @@ public:
 std::vector subst)
   {
 RegionParamList list (num_regions);
-for (size_t i = 0; i < subst.size (); i++)
+for (size_t i = 0; i < MIN (num_regions, subst.size ()); i++)
   list.regions.at (i) = subst.at (i);
 for (size_t i = subst.size (); i < num_regions; i++)
   {
diff --git a/gcc/testsuite/rust/compile/issue-3605.rs 
b/gcc/testsuite/rust/compile/issue-3605.rs
new file mode 100644
index ..05e6e48e66e3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3605.rs
@@ -0,0 +1,5 @@
+enum Foo<'a> {}
+
+enum Bar<'a> {
+in_band_def_explicit_impl(Foo<'a>),
+}


[gcc/devel/rust/master] gccrs: Fix ICE when doing shift checks on const decl

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:eecf0cd6857d269fc9be9a858f2ba02189d756cc

commit eecf0cd6857d269fc9be9a858f2ba02189d756cc
Author: Philip Herron 
Date:   Mon Mar 31 17:58:24 2025 +0100

gccrs: Fix ICE when doing shift checks on const decl

Const decls are just delcarations wrapping the value into the DECL_INITIAL
and the shift checks we have assume no decls are involved and its just flat
values. This patch simply unwraps the constant values if they exist.

Fixes Rust-GCC#3665

gcc/rust/ChangeLog:

* rust-gcc.cc (arithmetic_or_logical_expression): unwrap const decls

gcc/testsuite/ChangeLog:

* rust/compile/issue-3665.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/rust-gcc.cc | 6 ++
 gcc/testsuite/rust/compile/issue-3665.rs | 6 ++
 2 files changed, 12 insertions(+)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 1efd872ee8f7..3b0cd5b9afcf 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1074,6 +1074,12 @@ arithmetic_or_logical_expression 
(ArithmeticOrLogicalOperator op, tree left,
   if (left == error_mark_node || right == error_mark_node)
 return error_mark_node;
 
+  // unwrap the const decls if set
+  if (TREE_CODE (left) == CONST_DECL)
+left = DECL_INITIAL (left);
+  if (TREE_CODE (right) == CONST_DECL)
+right = DECL_INITIAL (right);
+
   /* We need to determine if we're doing floating point arithmetics of integer
  arithmetics. */
   bool floating_point = is_floating_point (left);
diff --git a/gcc/testsuite/rust/compile/issue-3665.rs 
b/gcc/testsuite/rust/compile/issue-3665.rs
new file mode 100644
index ..d66a81fc1aec
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3665.rs
@@ -0,0 +1,6 @@
+pub const uint_val: usize = 1;
+pub const uint_expr: usize = 1 << uint_val;
+
+pub fn test() -> usize {
+uint_expr
+}


[gcc/devel/rust/master] gccrs: Fix SEGV when type path resolver fails outright

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:765121736dfe3f5b319bbe9837880deda326394e

commit 765121736dfe3f5b319bbe9837880deda326394e
Author: Philip Herron 
Date:   Fri Mar 28 18:59:33 2025 +

gccrs: Fix SEGV when type path resolver fails outright

When we resolve paths we resolve to Types first we walk each segment to
the last module which has no type but then in the event that the child
of a module is not found we have a null root_tyty which needs to be caught
and turned into an ErrorType node.

Fixes Rust-GCC#3613

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-type.cc 
(TypeCheckType::resolve_root_path):
catch nullptr root_tyty

gcc/testsuite/ChangeLog:

* rust/compile/issue-3613.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-type.cc |  7 +++
 gcc/testsuite/rust/compile/issue-3613.rs   | 18 ++
 2 files changed, 25 insertions(+)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 5668838c79f3..630abb0d90e0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -360,6 +360,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, 
size_t *offset,
 seg->as_string ().c_str ());
  return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
}
+ else if (root_tyty == nullptr)
+   {
+ rust_error_at (seg->get_locus (),
+"unknown reference for resolved name: %qs",
+seg->as_string ().c_str ());
+ return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+   }
  return root_tyty;
}
 
diff --git a/gcc/testsuite/rust/compile/issue-3613.rs 
b/gcc/testsuite/rust/compile/issue-3613.rs
new file mode 100644
index ..f2e10921f671
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3613.rs
@@ -0,0 +1,18 @@
+mod m1 {
+pub enum Baz4 {
+foo1,
+foo2,
+}
+}
+
+fn bar(x: m1::foo) {
+// { dg-error "unknown reference for resolved name: .foo." "" { target 
*-*-* } .-1 }
+match x {
+m1::foo::foo1 => {}
+// { dg-error "failed to type resolve root segment" "" { target *-*-* 
} .-1 }
+m1::NodePosition::foo2 => {}
+// { dg-error "failed to type resolve root segment" "" { target *-*-* 
} .-1 }
+}
+}
+
+pub fn main() {}


[gcc/devel/rust/master] gccrs: Fix ICE in array ref constexpr

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:a0b21c94157d85f4ab87aa9aee83cb629678f72a

commit a0b21c94157d85f4ab87aa9aee83cb629678f72a
Author: Philip Herron 
Date:   Fri Mar 28 16:59:33 2025 +

gccrs: Fix ICE in array ref constexpr

Since 898d55ad7e2 was fixed to remove the VIEW_CONVERT_EXPR from
array expressions we can now turn on the array element access
const expr.

Fixes Rust-GCC#3563

gcc/rust/ChangeLog:

* backend/rust-constexpr.cc (eval_store_expression): turn this back 
on

gcc/testsuite/ChangeLog:

* rust/compile/issue-3563.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/backend/rust-constexpr.cc   |  6 ++
 gcc/testsuite/rust/compile/issue-3563.rs | 17 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/backend/rust-constexpr.cc 
b/gcc/rust/backend/rust-constexpr.cc
index 2f2bbbd921d1..dc2d6b1066be 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2697,10 +2697,8 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, 
bool lval,
  }
if (TREE_CODE (probe) == ARRAY_REF)
  {
-   // TODO
-   rust_unreachable ();
-   // elt = eval_and_check_array_index (ctx, probe, false,
-   //non_constant_p, overflow_p);
+   elt = eval_and_check_array_index (ctx, probe, false,
+ non_constant_p, overflow_p);
if (*non_constant_p)
  return t;
  }
diff --git a/gcc/testsuite/rust/compile/issue-3563.rs 
b/gcc/testsuite/rust/compile/issue-3563.rs
new file mode 100644
index ..46e762464b82
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3563.rs
@@ -0,0 +1,17 @@
+pub struct AA {
+pub data: [u8; 10],
+}
+
+impl AA {
+pub const fn new() -> Self {
+let mut res: AA = AA { data: [0; 10] };
+res.data[0] = 5;
+res
+}
+}
+
+static mut BB: AA = AA::new();
+
+fn main() {
+let _ptr = unsafe { &mut BB };
+}


[gcc/devel/rust/master] gccrs: Fix ICE when there are 2 functions named main

2025-04-02 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:8cd24f83386f0e7c20c80f1517d8236515767f51

commit 8cd24f83386f0e7c20c80f1517d8236515767f51
Author: Philip Herron 
Date:   Wed Apr 2 16:16:47 2025 +0100

gccrs: Fix ICE when there are 2 functions named main

We need to setup the main_identifier_node for MAIN_DECL_P checks in the
middle-end. But it is valid to have a main function/method on impl blocks.
So we need to flag if this is a "root" item or not, which is one that is
jsut an HIR::Function on part of the Crate::items as oppposed to a
HIR::Function which is part of an HIR::ImplBlock as part of the HIR::Crate.
Some small cleanups have been added here too.

Fixes Rust-GCC#3648

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: new flag is_root_item
* backend/rust-compile-base.h: update prototype
* backend/rust-compile-implitem.cc (CompileTraitItem::visit): 
update call
* backend/rust-compile-implitem.h: remove old debug internal error
* backend/rust-compile-item.cc (CompileItem::visit): update call
* backend/rust-compile-item.h: remove old debug
* backend/rust-compile-resolve-path.cc 
(HIRCompileBase::query_compile): update calls
* backend/rust-compile.cc: likewise
* typecheck/rust-hir-trait-resolve.cc 
(TraitResolver::resolve_path_to_trait):
remove assertion and error

gcc/testsuite/ChangeLog:

* rust/compile/issue-3648.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/backend/rust-compile-base.cc | 4 ++--
 gcc/rust/backend/rust-compile-base.h  | 3 ++-
 gcc/rust/backend/rust-compile-implitem.cc | 2 +-
 gcc/rust/backend/rust-compile-implitem.h  | 6 --
 gcc/rust/backend/rust-compile-item.cc | 6 +-
 gcc/rust/backend/rust-compile-item.h  | 4 
 gcc/rust/backend/rust-compile-resolve-path.cc | 9 -
 gcc/rust/backend/rust-compile.cc  | 2 +-
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  | 8 +++-
 gcc/testsuite/rust/compile/issue-3648.rs  | 8 
 10 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index d8a71f5d7eb6..f8c5fa99f795 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -663,7 +663,7 @@ get_abi (const AST::AttrVec &outer_attrs,
 
 tree
 HIRCompileBase::compile_function (
-  const std::string &fn_name, HIR::SelfParam &self_param,
+  bool is_root_item, const std::string &fn_name, HIR::SelfParam &self_param,
   std::vector &function_params,
   const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
   AST::AttrVec &outer_attrs, location_t locus, HIR::BlockExpr *function_body,
@@ -674,7 +674,7 @@ HIRCompileBase::compile_function (
 = canonical_path.get () + fntype->subst_as_string ();
 
   // we don't mangle the main fn since we haven't implemented the main shim
-  bool is_main_fn = fn_name.compare ("main") == 0;
+  bool is_main_fn = fn_name.compare ("main") == 0 && is_root_item;
   if (is_main_fn)
 {
   rust_assert (!main_identifier_node);
diff --git a/gcc/rust/backend/rust-compile-base.h 
b/gcc/rust/backend/rust-compile-base.h
index 323b1a025226..3ec1e2c6dffc 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -102,7 +102,8 @@ protected:
  HIR::Expr &const_value_expr, location_t locus,
  location_t expr_locus);
 
-  tree compile_function (const std::string &fn_name, HIR::SelfParam 
&self_param,
+  tree compile_function (bool is_root_item, const std::string &fn_name,
+HIR::SelfParam &self_param,
 std::vector &function_params,
 const HIR::FunctionQualifiers &qualifiers,
 HIR::Visibility &visibility, AST::AttrVec &outer_attrs,
diff --git a/gcc/rust/backend/rust-compile-implitem.cc 
b/gcc/rust/backend/rust-compile-implitem.cc
index 6a3c3b0e1c02..a30e11f04235 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -117,7 +117,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func)
   auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC);
   HIR::TraitFunctionDecl &function = func.get_decl ();
   tree fndecl
-= compile_function (function.get_function_name ().as_string (),
+= compile_function (false, function.get_function_name ().as_string (),
function.get_self (), function.get_function_params (),
function.get_qualifiers (), vis,
func.get_outer_attrs (), func.get_locus (),
diff --git a/gcc/rust/backend/rust-compile-implitem.h 
b/gcc/rust/backend/rust-compile-implitem.h
index 69933bff8c56..22189d4a23a9 100644
--- a/gcc/rust/backend/rust-compile-im