[gcc r15-4960] Deprecate the ARM simulator

2024-11-05 Thread Nick Clifton via Gcc-cvs
https://gcc.gnu.org/g:6543a214485c0a722152e34de37424f9a0104bbb

commit r15-4960-g6543a214485c0a722152e34de37424f9a0104bbb
Author: Nick Clifton 
Date:   Tue Nov 5 13:04:36 2024 +

Deprecate the ARM simulator

The ARM simulator is no longer able to simulator modern ARM cores, so it
is being deprecated.  Once this change has been active for a while - and
assuming that no problems have been found - the ARm simulator codebase
will be removed.

2024-11-05  Nick Clifton  

* configure.ac: Add sim to noconfigdirs for ARM targets.
* configure: Regenerate.

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

diff --git a/configure b/configure
index 8d031adafa82..a2e86731b085 100755
--- a/configure
+++ b/configure
@@ -3766,6 +3766,13 @@ case "${target}" in
 ;;
 esac
 
+# The ARM simulator has been deprecated for all ARM targets.
+case "${target}" in
+  arm*-*-*)
+noconfigdirs="$noconfigdirs sim"
+;;
+esac
+
 case "${target}" in
   *-*-chorusos)
 ;;
@@ -3777,7 +3784,7 @@ case "${target}" in
 ;;
   arm-*-darwin*)
 noconfigdirs="$noconfigdirs ld gas gdb gprof"
-noconfigdirs="$noconfigdirs sim target-rda"
+noconfigdirs="$noconfigdirs target-rda"
 ;;
   powerpc-*-darwin*)
 noconfigdirs="$noconfigdirs ld gas gdb gprof"
diff --git a/configure.ac b/configure.ac
index a688e9e24258..25419a1d2ab8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -991,6 +991,13 @@ case "${target}" in
 ;;
 esac
 
+# The ARM simulator has been deprecated for all ARM targets.
+case "${target}" in
+  arm*-*-*)
+noconfigdirs="$noconfigdirs sim"
+;;
+esac
+
 case "${target}" in
   *-*-chorusos)
 ;;
@@ -1002,7 +1009,7 @@ case "${target}" in
 ;;
   arm-*-darwin*)
 noconfigdirs="$noconfigdirs ld gas gdb gprof"
-noconfigdirs="$noconfigdirs sim target-rda"
+noconfigdirs="$noconfigdirs target-rda"
 ;;
   powerpc-*-darwin*)
 noconfigdirs="$noconfigdirs ld gas gdb gprof"


[gcc r14-10886] Fortran: Fix regressions with intent(out) class[PR115070, PR115348].

2024-11-05 Thread Paul Thomas via Gcc-cvs
https://gcc.gnu.org/g:c16e4ecd8fdc2230a313fe795333fa97652ba19f

commit r14-10886-gc16e4ecd8fdc2230a313fe795333fa97652ba19f
Author: Paul Thomas 
Date:   Tue Nov 5 15:54:45 2024 +

Fortran: Fix regressions with intent(out) class[PR115070, PR115348].

2024-11-05  Paul Thomas  

gcc/fortran
PR fortran/115070
PR fortran/115348
* trans-expr.cc (gfc_trans_class_init_assign): If all the
components of the default initializer are null for a scalar,
build an empty statement to prevent prior declarations from
disappearing.

gcc/testsuite/
PR fortran/115070
* gfortran.dg/ieee/pr115070.f90: New test.

PR fortran/115348
* gfortran.dg/pr115348.f90: New test.

Diff:
---
 gcc/fortran/trans-expr.cc   | 29 ++--
 gcc/testsuite/gfortran.dg/ieee/pr115070.f90 | 28 +++
 gcc/testsuite/gfortran.dg/pr115348.f90  | 35 +
 3 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 3a5a41401858..f182ea2ee1cd 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -1723,10 +1723,12 @@ gfc_trans_class_init_assign (gfc_code *code)
 {
   stmtblock_t block;
   tree tmp;
+  bool cmp_flag = true;
   gfc_se dst,src,memsz;
   gfc_expr *lhs, *rhs, *sz;
   gfc_component *cmp;
   gfc_symbol *sym;
+  gfc_ref *ref;
 
   gfc_start_block (&block);
 
@@ -1744,24 +1746,25 @@ gfc_trans_class_init_assign (gfc_code *code)
   rhs->rank = 0;
 
   /* Check def_init for initializers.  If this is an INTENT(OUT) dummy with all
- default initializer components NULL, return NULL_TREE and use the passed
- value as required by F2018(8.5.10).  */
+ default initializer components NULL, use the passed value even though
+ F2018(8.5.10) asserts that it should considered to be undefined. This is
+ needed for consistency with other brands.  */
   sym = code->expr1->expr_type == EXPR_VARIABLE ? code->expr1->symtree->n.sym
: NULL;
   if (code->op != EXEC_ALLOCATE
   && sym && sym->attr.dummy
   && sym->attr.intent == INTENT_OUT)
 {
-  if (!lhs->ref && lhs->symtree->n.sym->attr.dummy)
+  ref = rhs->ref;
+  while (ref && ref->next)
+   ref = ref->next;
+  cmp = ref->u.c.component->ts.u.derived->components;
+  for (; cmp; cmp = cmp->next)
{
- cmp = rhs->ref->next->u.c.component->ts.u.derived->components;
- for (; cmp; cmp = cmp->next)
-   {
- if (cmp->initializer)
-   break;
- else if (!cmp->next)
-   return NULL_TREE;
-   }
+ if (cmp->initializer)
+   break;
+ else if (!cmp->next)
+   cmp_flag = false;
}
 }
 
@@ -1775,7 +1778,7 @@ gfc_trans_class_init_assign (gfc_code *code)
   gfc_add_full_array_ref (lhs, tmparr);
   tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
 }
-  else
+  else if (cmp_flag)
 {
   /* Scalar initialization needs the _data component.  */
   gfc_add_data_component (lhs);
@@ -1805,6 +1808,8 @@ gfc_trans_class_init_assign (gfc_code *code)
tmp, build_empty_stmt (input_location));
}
 }
+  else
+tmp = build_empty_stmt (input_location);
 
   if (code->expr1->symtree->n.sym->attr.dummy
   && (code->expr1->symtree->n.sym->attr.optional
diff --git a/gcc/testsuite/gfortran.dg/ieee/pr115070.f90 
b/gcc/testsuite/gfortran.dg/ieee/pr115070.f90
new file mode 100644
index ..9378f770e2c6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ieee/pr115070.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+!
+! Test the fix for PR115070
+!
+! Contributed by Sebastien Bardeau  
+!
+module my_mod
+  type my_type
+integer :: a
+  contains
+final :: myfinal
+  end type my_type
+contains
+  subroutine my_sub(obs)
+use ieee_arithmetic
+class(my_type), intent(out) :: obs
+  end subroutine my_sub
+  subroutine myfinal (arg)
+type (my_type) :: arg
+print *, arg%a
+  end
+end module my_mod
+
+  use my_mod
+  type (my_type) :: z
+  z%a = 42
+  call my_sub (z)
+end
diff --git a/gcc/testsuite/gfortran.dg/pr115348.f90 
b/gcc/testsuite/gfortran.dg/pr115348.f90
new file mode 100644
index ..bc644b2f1c0c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr115348.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-fcheck=recursion" }
+!
+! Test the fix for pr115348.
+!
+! Contributed by Maxime van den Bossche  
+!
+module mymodule
+implicit none
+
+type mytype
+integer :: mynumber
+contains
+procedure :: myroutine
+end type mytype
+
+contains
+
+subroutine myroutine(self)
+class(mytype), intent(out) :: self
+
+self%mynumber = 1
+end subroutine myroutine
+end

[gcc r15-4961] c++: allow array mem-init with -fpermissive [PR116634]

2024-11-05 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:3545aab00152ed3db1d7ce6ca4e1671dde276980

commit r15-4961-g3545aab00152ed3db1d7ce6ca4e1671dde276980
Author: Jason Merrill 
Date:   Mon Nov 4 17:48:46 2024 -0500

c++: allow array mem-init with -fpermissive [PR116634]

We've accidentally accepted this forever (at least as far back as 4.7), but
it's always been ill-formed; this was PR59465.  And we didn't accept it for
scalar types.  But rather than switch to a hard error for this code, let's
give a permerror so affected code can continue to work with -fpermissive.

PR c++/116634

gcc/cp/ChangeLog:

* init.cc (can_init_array_with_p): Allow PR59465 case with
permerror.

gcc/testsuite/ChangeLog:

* g++.dg/diagnostic/aggr-init1.C: Expect warning with -fpermissive.
* g++.dg/init/array62.C: Adjust diagnostic.
* g++.dg/init/array63.C: Adjust diagnostic.
* g++.dg/init/array64.C: Adjust diagnostic.

Diff:
---
 gcc/cp/init.cc   | 4 +++-
 gcc/testsuite/g++.dg/diagnostic/aggr-init1.C | 3 ++-
 gcc/testsuite/g++.dg/init/array62.C  | 2 +-
 gcc/testsuite/g++.dg/init/array63.C  | 2 +-
 gcc/testsuite/g++.dg/init/array64.C  | 2 +-
 5 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 12c673efb2ac..62b3d6f6ce91 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -967,7 +967,9 @@ can_init_array_with_p (tree type, tree init)
return true;
 }
 
-  return false;
+  permerror (input_location, "array must be initialized "
+"with a brace-enclosed initializer");
+  return true;
 }
 
 /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
diff --git a/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C 
b/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C
index 3c32124d6fde..906d2564bda8 100644
--- a/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C
+++ b/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C
@@ -1,5 +1,6 @@
 // PR c++/116634
 // { dg-do compile { target c++11 } }
+// { dg-additional-options -fpermissive }
 
 namespace std {
   using size_t = decltype(sizeof(42));
@@ -20,7 +21,7 @@ private:
 template
 struct Any final {
 constexpr
-Any(ConstString (&&_vec)[N]) noexcept: vec(_vec){} // { dg-error "array" }
+Any(ConstString (&&_vec)[N]) noexcept: vec(_vec){} // { dg-warning "array" 
}
 
 ConstString vec[N];
 };
diff --git a/gcc/testsuite/g++.dg/init/array62.C 
b/gcc/testsuite/g++.dg/init/array62.C
index 2a786a36e4e8..6d3935d7a668 100644
--- a/gcc/testsuite/g++.dg/init/array62.C
+++ b/gcc/testsuite/g++.dg/init/array62.C
@@ -4,7 +4,7 @@
 struct string {} a[1];
 struct pair {
   string s[1];
-  pair() : s(a) {} // { dg-error "invalid initializer for array member" }
+  pair() : s(a) {} // { dg-error "array must be initialized" }
 };
 
 struct S {
diff --git a/gcc/testsuite/g++.dg/init/array63.C 
b/gcc/testsuite/g++.dg/init/array63.C
index 57e980561680..96bc9a64b26c 100644
--- a/gcc/testsuite/g++.dg/init/array63.C
+++ b/gcc/testsuite/g++.dg/init/array63.C
@@ -7,7 +7,7 @@ struct I {
 struct O {
 I a[2];
 static I const data[2];
-O() : a(data){}  // { dg-error "invalid initializer for array member" }
+O() : a(data){}  // { dg-error "array must be initialized" }
 };
 
 I const O::data[2] = {true, false};
diff --git a/gcc/testsuite/g++.dg/init/array64.C 
b/gcc/testsuite/g++.dg/init/array64.C
index e0afdfab39a5..bbdd70c6df8c 100644
--- a/gcc/testsuite/g++.dg/init/array64.C
+++ b/gcc/testsuite/g++.dg/init/array64.C
@@ -16,7 +16,7 @@ typedef UserType Array[my_size];
 class Foo
 {
 public:
-  Foo(Array& m) : m_(m) {};  // { dg-error "invalid initializer for array 
member" }
+  Foo(Array& m) : m_(m) {};  // { dg-error "array must be initialized" }
 private:
   Array m_;
 };


[gcc r15-4956] testsuite: fix testcase pr110279-1.c

2024-11-05 Thread Di Zhao via Gcc-cvs
https://gcc.gnu.org/g:5c19ba52519be975d4464b063d3d5a2c700dd241

commit r15-4956-g5c19ba52519be975d4464b063d3d5a2c700dd241
Author: Di Zhao 
Date:   Tue Nov 5 12:28:54 2024 +0800

testsuite: fix testcase pr110279-1.c

The test case is for targets that support FMA. Previously
the "target" selector is missed in dg-final command.

gcc/testsuite/ChangeLog:
PR tree-optimization/110279
* gcc.dg/pr110279-1.c: add target selector.

Diff:
---
 gcc/testsuite/gcc.dg/pr110279-1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr110279-1.c 
b/gcc/testsuite/gcc.dg/pr110279-1.c
index a8c7257b28d3..c4f94ea5810c 100644
--- a/gcc/testsuite/gcc.dg/pr110279-1.c
+++ b/gcc/testsuite/gcc.dg/pr110279-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile } */
+/* { dg-do compile { target { scalar_all_fma || { i?86-*-* x86_64-*-* } } } } 
*/
 /* { dg-options "-Ofast --param avoid-fma-max-bits=512 --param 
tree-reassoc-width=4 -fdump-tree-widening_mul-details" } */
 /* { dg-additional-options "-mcpu=generic" { target aarch64*-*-* } } */
 /* { dg-additional-options "-mfma" { target i?86-*-* x86_64-*-* } } */
@@ -64,4 +64,4 @@ foo3 (data_e a, data_e b, data_e c, data_e d)
   return result;
 }
 
-/* { dg-final { scan-tree-dump-times "Generated FMA" 3 "widening_mul"} } */
\ No newline at end of file
+/* { dg-final { scan-tree-dump-times "Generated FMA" 3 "widening_mul" } } */


[gcc r15-4952] i386: Handling exception input of __builtin_ia32_prefetch. [PR117416]

2024-11-05 Thread Hu via Gcc-cvs
https://gcc.gnu.org/g:ea46a216d48597b220ae69e79f6513c763f953be

commit r15-4952-gea46a216d48597b220ae69e79f6513c763f953be
Author: Hu, Lin1 
Date:   Mon Nov 4 14:52:56 2024 +0800

i386: Handling exception input of __builtin_ia32_prefetch. [PR117416]

op1 should be between 0 and 2. Add an error handler, and op3 should be 0
or 1, raise a warning, when op3 is an invalid value.

gcc/ChangeLog:

PR target/117416
* config/i386/i386-expand.cc (ix86_expand_builtin): Raise warning 
when
op1 isn't in range of [0, 2] and set op1 as const0_rtx, and raise
warning when op3 isn't in range of [0, 1].

gcc/testsuite/ChangeLog:

PR target/117416
* gcc.target/i386/pr117416-1.c: New test.
* gcc.target/i386/pr117416-2.c: Ditto.

Diff:
---
 gcc/config/i386/i386-expand.cc | 11 +++
 gcc/testsuite/gcc.target/i386/pr117416-1.c | 13 +
 gcc/testsuite/gcc.target/i386/pr117416-2.c | 13 +
 3 files changed, 37 insertions(+)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 6eef27f3fcda..ff07ab40848e 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -14202,6 +14202,13 @@ ix86_expand_builtin (tree exp, rtx target, rtx 
subtarget,
return const0_rtx;
  }
 
+   if (!IN_RANGE (INTVAL (op1), 0, 2))
+ {
+   warning (0, "invalid second argument to"
+" %<__builtin_ia32_prefetch%>; using zero");
+   op1 = const0_rtx;
+ }
+
if (INTVAL (op3) == 1)
  {
if (INTVAL (op2) < 2 || INTVAL (op2) > 3)
@@ -14224,6 +14231,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx 
subtarget,
  }
else
  {
+   if (INTVAL (op3) != 0)
+ warning (0, "invalid forth argument to"
+ " %<__builtin_ia32_prefetch%>; using zero");
+
if (!address_operand (op0, VOIDmode))
  {
op0 = convert_memory_address (Pmode, op0);
diff --git a/gcc/testsuite/gcc.target/i386/pr117416-1.c 
b/gcc/testsuite/gcc.target/i386/pr117416-1.c
new file mode 100644
index ..65788f268d9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr117416-1.c
@@ -0,0 +1,13 @@
+/* PR target/117416 */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include 
+
+void* p;
+
+void extern
+prefetch_test (void)
+{
+  __builtin_ia32_prefetch (p, 5, 0, 0); /* { dg-warning "invalid second 
argument to '__builtin_ia32_prefetch'; using zero" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr117416-2.c 
b/gcc/testsuite/gcc.target/i386/pr117416-2.c
new file mode 100644
index ..07799e36cfe1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr117416-2.c
@@ -0,0 +1,13 @@
+/* PR target/117416 */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include 
+
+void* p;
+
+void extern
+prefetch_test (void)
+{
+  __builtin_ia32_prefetch (p, 0, 0, 2); /* { dg-warning "invalid forth 
argument to '__builtin_ia32_prefetch'; using zero" } */
+}


[gcc r15-4962] testsuite: Fix up gcc.target/powerpc/safe-indirect-jump-3.c test [PR117444]

2024-11-05 Thread Peter Bergner via Gcc-cvs
https://gcc.gnu.org/g:f185a89fc4b6e6f5ae5475cd7c723b3acf39976b

commit r15-4962-gf185a89fc4b6e6f5ae5475cd7c723b3acf39976b
Author: Peter Bergner 
Date:   Tue Nov 5 10:30:46 2024 -0600

testsuite: Fix up gcc.target/powerpc/safe-indirect-jump-3.c test [PR117444]

The test safe-indirect-jump-3.c FAILs on powerpc64le-linux with the change
in jump table generation behavior with commit r15-4756-g06bc3a734e8890,
since it is compiled without optimization and expects jump tables to be
generated.  Add an explicit -fjump-tables to dg-options to get the old
behavior back.

2024-11-05  Peter Bergner  

gcc/testsuite/
PR testsuite/117444
* gcc.target/powerpc/safe-indirect-jump-3.c: Add -fjump-tables to
dg-options.

Diff:
---
 gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c 
b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c
index 87881fb18fc5..f5a7100a9ff8 100644
--- a/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/safe-indirect-jump-3.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mno-speculate-indirect-jumps" } */
+/* { dg-options "-fjump-tables -mno-speculate-indirect-jumps" } */
 /* { dg-warning "'-mno-speculate-indirect-jumps' is deprecated" "" { target 
*-*-* } 0 } */
 
 /* Test for deliberate misprediction of jump tables.  */


[gcc r15-4963] PR target/117449: Restrict vector rotate match and split to pre-reload

2024-11-05 Thread Kyrylo Tkachov via Gcc-cvs
https://gcc.gnu.org/g:161e246cf32f1298400aa3c1d86110490a3cd0ce

commit r15-4963-g161e246cf32f1298400aa3c1d86110490a3cd0ce
Author: Kyrylo Tkachov 
Date:   Tue Nov 5 05:10:22 2024 -0800

PR target/117449: Restrict vector rotate match and split to pre-reload

The vector rotate splitter has some logic to deal with post-reload splitting
but not all cases in aarch64_emit_opt_vec_rotate are post-reload-safe.
In particular the ROTATE+XOR expansion for TARGET_SHA3 can create RTL that
can later be simplified to a simple ROTATE post-reload, which would then
match the insn again and try to split it.
So do a clean split pre-reload and avoid going down this path post-reload
by restricting the insn_and_split to can_create_pseudo_p ().

Bootstrapped and tested on aarch64-none-linux.

Signed-off-by: Kyrylo Tkachov 
gcc/

PR target/117449
* config/aarch64/aarch64-simd.md (*aarch64_simd_rotate_imm):
Match only when can_create_pseudo_p ().
* config/aarch64/aarch64.cc (aarch64_emit_opt_vec_rotate): Assume
can_create_pseudo_p ().

gcc/testsuite/

PR target/117449
* gcc.c-torture/compile/pr117449.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64-simd.md |  6 --
 gcc/config/aarch64/aarch64.cc  | 11 ++-
 gcc/testsuite/gcc.c-torture/compile/pr117449.c |  8 
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index a91222b6e3b2..cfe95bd4c316 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1296,11 +1296,13 @@
 
 ;; After all the combinations and propagations of ROTATE have been
 ;; attempted split any remaining vector rotates into SHL + USRA sequences.
+;; Don't match this after reload as the various possible sequence for this
+;; require temporary registers.
 (define_insn_and_split "*aarch64_simd_rotate_imm"
   [(set (match_operand:VDQ_I 0 "register_operand" "=&w")
(rotate:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
  (match_operand:VDQ_I 2 "aarch64_simd_lshift_imm")))]
-  "TARGET_SIMD"
+  "TARGET_SIMD && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(set (match_dup 3)
@@ -1316,7 +1318,7 @@
 if (aarch64_emit_opt_vec_rotate (operands[0], operands[1], operands[2]))
   DONE;
 
-operands[3] = reload_completed ? operands[0] : gen_reg_rtx (mode);
+operands[3] = gen_reg_rtx (mode);
 rtx shft_amnt = unwrap_const_vec_duplicate (operands[2]);
 int bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
 operands[4]
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 9347e06f0e9e..f2b53475adbe 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -16030,6 +16030,8 @@ aarch64_emit_opt_vec_rotate (rtx dst, rtx reg, rtx 
amnt_vec)
   gcc_assert (CONST_INT_P (amnt));
   HOST_WIDE_INT rotamnt = UINTVAL (amnt);
   machine_mode mode = GET_MODE (reg);
+  /* Don't end up here after reload.  */
+  gcc_assert (can_create_pseudo_p ());
   /* Rotates by half the element width map down to REV* instructions and should
  always be preferred when possible.  */
   if (rotamnt == GET_MODE_UNIT_BITSIZE (mode) / 2
@@ -16037,11 +16039,10 @@ aarch64_emit_opt_vec_rotate (rtx dst, rtx reg, rtx 
amnt_vec)
 return true;
   /* 64 and 128-bit vector modes can use the XAR instruction
  when available.  */
-  else if (can_create_pseudo_p ()
-  && ((TARGET_SHA3 && mode == V2DImode)
-  || (TARGET_SVE2
-  && (known_eq (GET_MODE_SIZE (mode), 8)
-  || known_eq (GET_MODE_SIZE (mode), 16)
+  else if ((TARGET_SHA3 && mode == V2DImode)
+  || (TARGET_SVE2
+  && (known_eq (GET_MODE_SIZE (mode), 8)
+  || known_eq (GET_MODE_SIZE (mode), 16
 {
   rtx zeroes = aarch64_gen_shareable_zero (mode);
   rtx xar_op
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr117449.c 
b/gcc/testsuite/gcc.c-torture/compile/pr117449.c
new file mode 100644
index ..8ae0071fca6b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr117449.c
@@ -0,0 +1,8 @@
+/* { dg-additional-options "-march=armv8.2-a+sha3" { target aarch64*-*-* } } */
+
+unsigned long *a;
+int i;
+void f() {
+  for (i = 0; i < 80; i++)
+a[i] = (a[i] >> 8 | a[i] << 64 - 8) ^ a[i];
+}


[gcc r14-10887] c++: allow array mem-init with -fpermissive [PR116634]

2024-11-05 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:ce25ca4da198ebc269d41ee6a9ac880ae8f67ad6

commit r14-10887-gce25ca4da198ebc269d41ee6a9ac880ae8f67ad6
Author: Jason Merrill 
Date:   Mon Nov 4 17:48:46 2024 -0500

c++: allow array mem-init with -fpermissive [PR116634]

We've accidentally accepted this forever (at least as far back as 4.7), but
it's always been ill-formed; this was PR59465.  And we didn't accept it for
scalar types.  But rather than switch to a hard error for this code, let's
give a permerror so affected code can continue to work with -fpermissive.

PR c++/116634

gcc/cp/ChangeLog:

* init.cc (can_init_array_with_p): Allow PR59465 case with
permerror.

gcc/testsuite/ChangeLog:

* g++.dg/diagnostic/aggr-init1.C: Expect warning with -fpermissive.
* g++.dg/init/array62.C: Adjust diagnostic.
* g++.dg/init/array63.C: Adjust diagnostic.
* g++.dg/init/array64.C: Adjust diagnostic.

(cherry picked from commit 3545aab00152ed3db1d7ce6ca4e1671dde276980)

Diff:
---
 gcc/cp/init.cc   |  4 ++-
 gcc/testsuite/g++.dg/diagnostic/aggr-init1.C | 37 
 gcc/testsuite/g++.dg/init/array62.C  |  2 +-
 gcc/testsuite/g++.dg/init/array63.C  |  2 +-
 gcc/testsuite/g++.dg/init/array64.C  |  2 +-
 5 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index c5ba82c86648..5a994378451b 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -962,7 +962,9 @@ can_init_array_with_p (tree type, tree init)
return true;
 }
 
-  return false;
+  permerror (input_location, "array must be initialized "
+"with a brace-enclosed initializer");
+  return true;
 }
 
 /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
diff --git a/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C 
b/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C
new file mode 100644
index ..b4b2d9e69e1d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C
@@ -0,0 +1,37 @@
+// PR c++/116634
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -fpermissive }
+
+namespace std {
+  using size_t = decltype(sizeof(42));
+}
+
+class ConstString final {
+public:
+constexpr ConstString() noexcept: buf(), len(0) {}
+template
+constexpr ConstString(const char (&a)[N]): buf(a), len(N - 1) {}
+constexpr ConstString(const ConstString &c1): buf(c1.buf), 
len(static_cast(c1.len)) {}
+
+private:
+const char* buf;
+int len;
+};
+
+template
+struct Any final {
+constexpr
+Any(ConstString (&&_vec)[N]) noexcept: vec(_vec){} // { dg-warning "array" 
}
+
+ConstString vec[N];
+};
+
+template
+constexpr static
+auto Any_of(const char (&...c1)[N1]) -> Any(sizeof...(N1))> {
+  return {{ConstString(c1)...}};
+}
+
+int main() {
+  constexpr static const auto aa1 = Any_of("abcd", "def");
+}
diff --git a/gcc/testsuite/g++.dg/init/array62.C 
b/gcc/testsuite/g++.dg/init/array62.C
index 2a786a36e4e8..6d3935d7a668 100644
--- a/gcc/testsuite/g++.dg/init/array62.C
+++ b/gcc/testsuite/g++.dg/init/array62.C
@@ -4,7 +4,7 @@
 struct string {} a[1];
 struct pair {
   string s[1];
-  pair() : s(a) {} // { dg-error "invalid initializer for array member" }
+  pair() : s(a) {} // { dg-error "array must be initialized" }
 };
 
 struct S {
diff --git a/gcc/testsuite/g++.dg/init/array63.C 
b/gcc/testsuite/g++.dg/init/array63.C
index 57e980561680..96bc9a64b26c 100644
--- a/gcc/testsuite/g++.dg/init/array63.C
+++ b/gcc/testsuite/g++.dg/init/array63.C
@@ -7,7 +7,7 @@ struct I {
 struct O {
 I a[2];
 static I const data[2];
-O() : a(data){}  // { dg-error "invalid initializer for array member" }
+O() : a(data){}  // { dg-error "array must be initialized" }
 };
 
 I const O::data[2] = {true, false};
diff --git a/gcc/testsuite/g++.dg/init/array64.C 
b/gcc/testsuite/g++.dg/init/array64.C
index e0afdfab39a5..bbdd70c6df8c 100644
--- a/gcc/testsuite/g++.dg/init/array64.C
+++ b/gcc/testsuite/g++.dg/init/array64.C
@@ -16,7 +16,7 @@ typedef UserType Array[my_size];
 class Foo
 {
 public:
-  Foo(Array& m) : m_(m) {};  // { dg-error "invalid initializer for array 
member" }
+  Foo(Array& m) : m_(m) {};  // { dg-error "array must be initialized" }
 private:
   Array m_;
 };


[gcc r15-4954] Support vector float_truncate for SF to BF.

2024-11-05 Thread hongtao Liu via Gcc-cvs
https://gcc.gnu.org/g:a17acf4f25f0ce9b8dce24f25867500a3b093b57

commit r15-4954-ga17acf4f25f0ce9b8dce24f25867500a3b093b57
Author: liuhongt 
Date:   Wed Oct 23 00:51:00 2024 -0700

Support vector float_truncate for SF to BF.

Generate native instruction whenever possible, otherwise use vector
permutation with odd indices.

gcc/ChangeLog:

* config/i386/i386-expand.cc
(ix86_expand_vector_sf2bf_with_vec_perm): New function.
* config/i386/i386-protos.h
(ix86_expand_vector_sf2bf_with_vec_perm): New declare.
* config/i386/mmx.md (truncv2sfv2bf2): New expander.
* config/i386/sse.md (truncv4sfv4bf2): Ditto.
(truncv8sfv8bf2): Ditto.
(truncv16sfv16bf2): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/i386/avx512bf16-truncsfbf.c: New test.
* gcc.target/i386/avx512bw-truncsfbf.c: New test.
* gcc.target/i386/ssse3-truncsfbf.c: New test.

Diff:
---
 gcc/config/i386/i386-expand.cc | 38 ++
 gcc/config/i386/i386-protos.h  |  1 +
 gcc/config/i386/mmx.md | 18 +
 gcc/config/i386/sse.md | 44 +
 .../gcc.target/i386/avx512bf16-truncsfbf.c |  5 +++
 gcc/testsuite/gcc.target/i386/avx512bw-truncsfbf.c | 46 ++
 gcc/testsuite/gcc.target/i386/ssse3-truncsfbf.c| 20 ++
 7 files changed, 172 insertions(+)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index ff07ab40848e..5ee9973bd3e3 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -26842,4 +26842,42 @@ ix86_expand_trunc_with_avx2_noavx512f (rtx output, rtx 
input, machine_mode cvt_m
   emit_move_insn (output, gen_lowpart (out_mode, d.target));
 }
 
+/* Implement truncv8sfv8bf2 with vector permutation.  */
+void
+ix86_expand_vector_sf2bf_with_vec_perm (rtx dest, rtx src)
+{
+  machine_mode vperm_mode, src_mode = GET_MODE (src);
+  switch (src_mode)
+{
+case V16SFmode:
+  vperm_mode = V32BFmode;
+  break;
+case V8SFmode:
+  vperm_mode = V16BFmode;
+  break;
+case V4SFmode:
+  vperm_mode = V8BFmode;
+  break;
+default:
+  gcc_unreachable ();
+}
+
+  int nelt = GET_MODE_NUNITS (vperm_mode);
+  vec_perm_builder sel (nelt, nelt, 1);
+  sel.quick_grow (nelt);
+  for (int i = 0; i != nelt; i++)
+sel[i] = (2 * i + 1) % nelt;
+  vec_perm_indices indices (sel, 1, nelt);
+
+  rtx target = gen_reg_rtx (vperm_mode);
+  rtx op0 = lowpart_subreg (vperm_mode,
+   force_reg (src_mode, src),
+   src_mode);
+  bool ok = targetm.vectorize.vec_perm_const (vperm_mode, vperm_mode,
+ target, op0, op0, indices);
+  gcc_assert (ok);
+  emit_move_insn (dest, lowpart_subreg (GET_MODE (dest), target, vperm_mode));
+}
+
+
 #include "gt-i386-expand.h"
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index c1f9147769cb..55ffdb9dcf1d 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -258,6 +258,7 @@ extern int ix86_ternlog_idx (rtx op, rtx *args);
 extern bool ix86_ternlog_operand_p (rtx op);
 extern rtx ix86_expand_ternlog (machine_mode mode, rtx op0, rtx op1, rtx op2,
int idx, rtx target);
+extern void ix86_expand_vector_sf2bf_with_vec_perm (rtx, rtx);
 
 #ifdef TREE_CODE
 extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 506f4cab6a81..5c776ec0aba4 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -2994,6 +2994,24 @@
   DONE;
 })
 
+(define_expand "truncv2sfv2bf2"
+  [(set (match_operand:V2BF 0 "register_operand")
+   (float_truncate:V2BF
+ (match_operand:V2SF 1 "nonimmediate_operand")))]
+  "TARGET_SSSE3 && TARGET_MMX_WITH_SSE"
+{
+  rtx op1 = gen_reg_rtx (V4SFmode);
+  rtx op0 = gen_reg_rtx (V4BFmode);
+
+  emit_move_insn (op1, lowpart_subreg (V4SFmode,
+  force_reg (V2SFmode, operands[1]),
+  V2SFmode));
+  emit_insn (gen_truncv4sfv4bf2 (op0, op1));
+
+  emit_move_insn (operands[0], lowpart_subreg (V2BFmode, op0, V4BFmode));
+  DONE;
+})
+
 ;
 ;;
 ;; Parallel integral arithmetic
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 15ed8ff99cbd..48592798fb25 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -30984,6 +30984,24 @@
   "TARGET_AVX512BF16"
   "vcvtne2ps2bf16\t{%2, %1, %0|%0, %1, %2}")
 
+(define_expand "truncv4sfv4bf2"
+  [(set (match_operand:V4BF 0 "register_operand")
+ (float_truncate:V4BF
+   (match_operand:V4SF 1 "nonimmediate_operand")))]
+  "TARGET_SS

[gcc r15-4955] Support vector float_extend from __bf16 to float.

2024-11-05 Thread hongtao Liu via Gcc-cvs
https://gcc.gnu.org/g:648bd1fcc6acfc56e08f4ad8146a80910cfacfd7

commit r15-4955-g648bd1fcc6acfc56e08f4ad8146a80910cfacfd7
Author: liuhongt 
Date:   Wed Oct 23 23:51:20 2024 -0700

Support vector float_extend from __bf16 to float.

It's supported by vector permutation with zero vector.

gcc/ChangeLog:

* config/i386/i386-expand.cc
(ix86_expand_vector_bf2sf_with_vec_perm): New function.
* config/i386/i386-protos.h
(ix86_expand_vector_bf2sf_with_vec_perm): New Declare.
* config/i386/mmx.md (extendv2bfv2sf2): New expander.
* config/i386/sse.md (extend2):
Ditto.
(VF1_AVX512BW): New mode iterator.
(sf_cvt_bf16): Add V4SF.
(sf_cvt_bf16_lower): New mode attr.

gcc/testsuite/ChangeLog:

* gcc.target/i386/avx512bw-extendbf2sf.c: New test.
* gcc.target/i386/sse2-extendbf2sf.c: New test.

Diff:
---
 gcc/config/i386/i386-expand.cc | 39 ++
 gcc/config/i386/i386-protos.h  |  2 +
 gcc/config/i386/mmx.md | 18 +
 gcc/config/i386/sse.md | 20 +-
 .../gcc.target/i386/avx512bw-extendbf2sf.c | 46 ++
 gcc/testsuite/gcc.target/i386/sse2-extendbf2sf.c   | 20 ++
 6 files changed, 144 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 5ee9973bd3e3..5c4a8e07d621 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -26879,5 +26879,44 @@ ix86_expand_vector_sf2bf_with_vec_perm (rtx dest, rtx 
src)
   emit_move_insn (dest, lowpart_subreg (GET_MODE (dest), target, vperm_mode));
 }
 
+/* Implement extendv8bf2v8sf2 with vector permutation.  */
+void
+ix86_expand_vector_bf2sf_with_vec_perm (rtx dest, rtx src)
+{
+  machine_mode vperm_mode, src_mode = GET_MODE (src);
+  switch (src_mode)
+{
+case V16BFmode:
+  vperm_mode = V32BFmode;
+  break;
+case V8BFmode:
+  vperm_mode = V16BFmode;
+  break;
+case V4BFmode:
+  vperm_mode = V8BFmode;
+  break;
+default:
+  gcc_unreachable ();
+}
+
+  int nelt = GET_MODE_NUNITS (vperm_mode);
+  vec_perm_builder sel (nelt, nelt, 1);
+  sel.quick_grow (nelt);
+  for (int i = 0, k = 0, j = nelt; i != nelt; i++)
+sel[i] = i & 1 ? j++ : k++;
+
+  vec_perm_indices indices (sel, 2, nelt);
+
+  rtx target = gen_reg_rtx (vperm_mode);
+  rtx op1 = lowpart_subreg (vperm_mode,
+   force_reg (src_mode, src),
+   src_mode);
+  rtx op0 = CONST0_RTX (vperm_mode);
+  bool ok = targetm.vectorize.vec_perm_const (vperm_mode, vperm_mode,
+ target, op0, op1, indices);
+  gcc_assert (ok);
+  emit_move_insn (dest, lowpart_subreg (GET_MODE (dest), target, vperm_mode));
+}
+
 
 #include "gt-i386-expand.h"
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 55ffdb9dcf1d..c26ae5e4f1d2 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -259,6 +259,8 @@ extern bool ix86_ternlog_operand_p (rtx op);
 extern rtx ix86_expand_ternlog (machine_mode mode, rtx op0, rtx op1, rtx op2,
int idx, rtx target);
 extern void ix86_expand_vector_sf2bf_with_vec_perm (rtx, rtx);
+extern void ix86_expand_vector_bf2sf_with_vec_perm (rtx, rtx);
+
 
 #ifdef TREE_CODE
 extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 5c776ec0aba4..021ac90ae2a0 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -3012,6 +3012,24 @@
   DONE;
 })
 
+(define_expand "extendv2bfv2sf2"
+  [(set (match_operand:V2SF 0 "register_operand")
+   (float_extend:V2SF
+ (match_operand:V2BF 1 "nonimmediate_operand")))]
+  "TARGET_SSE2 && TARGET_MMX_WITH_SSE"
+{
+  rtx op0 = gen_reg_rtx (V4SFmode);
+  rtx op1 = gen_reg_rtx (V4BFmode);
+
+  emit_move_insn (op1, lowpart_subreg (V4BFmode,
+  force_reg (V2BFmode, operands[1]),
+  V2BFmode));
+  emit_insn (gen_extendv4bfv4sf2 (op0, op1));
+
+  emit_move_insn (operands[0], lowpart_subreg (V2SFmode, op0, V4SFmode));
+  DONE;
+})
+
 ;
 ;;
 ;; Parallel integral arithmetic
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 48592798fb25..5eeb3ab221a1 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -539,6 +539,9 @@
 (define_mode_iterator VF1_AVX512VL
   [(V16SF "TARGET_EVEX512") (V8SF "TARGET_AVX512VL") (V4SF "TARGET_AVX512VL")])
 
+(define_mode_iterator VF1_AVX512BW
+  [(V16SF "TARGET_EVEX512 && TARGET_EVEX512") (V8SF "TARGET_AVX2") V4SF])
+
 (define_mode_iterator VF1_AVX10_2
   [(V16SF "TARGET_AVX10_2

[gcc r15-4957] c++: Defer -fstrong-eval-order processing to template instantiation time [PR117158]

2024-11-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:b1d92aeb8583c8d1491c97703680c5fb88ed1fe4

commit r15-4957-gb1d92aeb8583c8d1491c97703680c5fb88ed1fe4
Author: Simon Martin 
Date:   Tue Nov 5 10:07:42 2024 +0100

c++: Defer -fstrong-eval-order processing to template instantiation time 
[PR117158]

Since r10-3793-g1a37b6d9a7e57c, we ICE upon the following valid code
with -std=c++17 and above

=== cut here ===
struct Base {
  unsigned int *intarray;
};
template  struct Sub : public Base {
  bool Get(int i) {
return (Base::intarray[++i] == 0);
  }
};
=== cut here ===

The problem is that from c++17 on, we use -fstrong-eval-order and need
to wrap the array access expression into a SAVE_EXPR. We do so at
template declaration time, and end up calling contains_placeholder_p
with a SCOPE_REF, that it does not handle well.

This patch fixes this by deferring the wrapping into SAVE_EXPR to
instantiation time for templates, when the SCOPE_REF will have been
turned into a COMPONENT_REF.

PR c++/117158

gcc/cp/ChangeLog:

* typeck.cc (cp_build_array_ref): Only wrap array expression
into a SAVE_EXPR at template instantiation time.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/eval-order13.C: New test.
* g++.dg/parse/crash77.C: New test.

Diff:
---
 gcc/cp/typeck.cc  |  3 ++-
 gcc/testsuite/g++.dg/cpp1z/eval-order13.C | 29 +
 gcc/testsuite/g++.dg/parse/crash77.C  | 13 +
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 6ce1bb61fe7b..439681216bed 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4092,7 +4092,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 tree ar = cp_default_conversion (array, complain);
 tree ind = cp_default_conversion (idx, complain);
 
-if (!first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
+if (!processing_template_decl
+   && !first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
   ar = first = save_expr (ar);
 
 /* Put the integer in IND to simplify error checking.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/eval-order13.C 
b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
new file mode 100644
index ..6e8ebeb30967
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
@@ -0,0 +1,29 @@
+// PR c++/117158 - Similar to eval-order7.C, only with templates.
+// { dg-do run { target c++11 } }
+// { dg-options "-fstrong-eval-order" }
+
+int a[4] = { 1, 2, 3, 4 };
+int b[4] = { 5, 6, 7, 8 };
+
+struct Base {
+  int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  int Get(int i) {
+Base::intarray = a;
+int r = Base::intarray[(Base::intarray = b, i)];
+if (Base::intarray != b)
+  __builtin_abort ();
+return r;
+  }
+};
+
+int
+main ()
+{
+  Sub s;
+  if (s.Get (3) != 4)
+__builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C 
b/gcc/testsuite/g++.dg/parse/crash77.C
new file mode 100644
index ..729362eb5991
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash77.C
@@ -0,0 +1,13 @@
+// PR c++/117158
+// { dg-do "compile" }
+
+struct Base {
+  unsigned int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  bool Get(int i) {
+return (Base::intarray[++i] == 0);
+  }
+};


[gcc r15-4958] c++: Don't crash upon invalid placement new operator [PR117101]

2024-11-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:5821f5c8c89a054e34cea00e042996dfdcd7e102

commit r15-4958-g5821f5c8c89a054e34cea00e042996dfdcd7e102
Author: Simon Martin 
Date:   Tue Nov 5 10:16:39 2024 +0100

c++: Don't crash upon invalid placement new operator [PR117101]

We currently crash upon the following invalid code (notice the "void
void**" parameter)

=== cut here ===
using size_t = decltype(sizeof(int));
void *operator new(size_t, void void **p) noexcept { return p; }
int x;
void f() {
int y;
new (&y) int(x);
}
=== cut here ===

The problem is that in this case, we end up with a NULL_TREE parameter
list for the new operator because of the error, and (1) coerce_new_type
wrongly complains about the first parameter type not being size_t,
(2) std_placement_new_fn_p blindly accesses the parameter list, hence a
crash.

This patch does NOT address #1 since we can't easily distinguish between
a new operator declaration without parameters from one with erroneous
parameters (and it's not worth the risk to refactor and break things for
an error recovery issue) hence a dg-bogus in new52.C, but it does
address #2 and the ICE by simply checking the first parameter against
NULL_TREE.

It also adds a new testcase checking that we complain about new
operators with no or invalid first parameters, since we did not have
any.

PR c++/117101

gcc/cp/ChangeLog:

* init.cc (std_placement_new_fn_p): Check first_arg against
NULL_TREE.

gcc/testsuite/ChangeLog:

* g++.dg/init/new52.C: New test.
* g++.dg/init/new53.C: New test.

Diff:
---
 gcc/cp/init.cc|  5 +++--
 gcc/testsuite/g++.dg/init/new52.C | 14 ++
 gcc/testsuite/g++.dg/init/new53.C |  8 
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 0527f53550db..12c673efb2ac 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -2980,8 +2980,9 @@ std_placement_new_fn_p (tree alloc_fn)
   if (DECL_NAMESPACE_SCOPE_P (alloc_fn))
 {
   tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
-  if ((TREE_VALUE (first_arg) == ptr_type_node)
- && TREE_CHAIN (first_arg) == void_list_node)
+  if (first_arg
+ && (TREE_VALUE (first_arg) == ptr_type_node)
+ && (TREE_CHAIN (first_arg) == void_list_node))
return true;
 }
   return false;
diff --git a/gcc/testsuite/g++.dg/init/new52.C 
b/gcc/testsuite/g++.dg/init/new52.C
new file mode 100644
index ..5eee2135724d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new52.C
@@ -0,0 +1,14 @@
+// PR c++/117101
+// { dg-do "compile" { target c++11 } }
+
+using size_t = decltype(sizeof(int));
+void* operator new(size_t, // { dg-bogus "first parameter" "" { xfail *-*-* } }
+  void void **p) noexcept // { dg-error "two or more" }
+{
+  return p; // { dg-error "not declared" }
+}
+int x;
+void f() {
+int y;
+new (&y) int(x);
+}
diff --git a/gcc/testsuite/g++.dg/init/new53.C 
b/gcc/testsuite/g++.dg/init/new53.C
new file mode 100644
index ..93d49dbd6c1f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new53.C
@@ -0,0 +1,8 @@
+// Check that we reject operator new with no argument or non-size_t first
+// argument.
+// { dg-do "compile" }
+
+void* operator new(); // { dg-error "takes type .size_t." }
+void* operator new(char); // { dg-error "takes type .size_t." }
+void* operator new(char*); // { dg-error "takes type .size_t." }
+void* operator new(char&); // { dg-error "takes type .size_t." }


[gcc r15-4959] c++: Fix crash during NRV optimization with invalid input [PR117099, PR117129]

2024-11-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:f31b72b75ef7cde61469c774162db7b1cc4c3d03

commit r15-4959-gf31b72b75ef7cde61469c774162db7b1cc4c3d03
Author: Simon Martin 
Date:   Tue Nov 5 10:44:34 2024 +0100

c++: Fix crash during NRV optimization with invalid input [PR117099, 
PR117129]

PR117099 and PR117129 are ICEs upon invalid code that happen when NRVO
is activated, and both due to the fact that we don't consistently set
current_function_return_value to error_mark_node upon error in
finish_return_expr.

This patch fixes this inconsistency which fixes both cases since we skip
calling finalize_nrv when current_function_return_value is
error_mark_node.

PR c++/117099
PR c++/117129

gcc/cp/ChangeLog:

* typeck.cc (check_return_expr): Upon error, set
current_function_return_value to error_mark_node.

gcc/testsuite/ChangeLog:

* g++.dg/parse/crash78.C: New test.
* g++.dg/parse/crash78a.C: New test.
* g++.dg/parse/crash79.C: New test.

Diff:
---
 gcc/cp/typeck.cc  |  8 +++-
 gcc/testsuite/g++.dg/parse/crash78.C  | 15 +++
 gcc/testsuite/g++.dg/parse/crash78a.C | 22 ++
 gcc/testsuite/g++.dg/parse/crash79.C  | 15 +++
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 439681216bed..4c15e26f692a 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -11239,6 +11239,8 @@ check_return_expr (tree retval, bool *no_warning, bool 
*dangling)
   "function returning %qT", valtype);
   /* Remember that this function did return.  */
   current_function_returns_value = 1;
+  /* But suppress NRV  .*/
+  current_function_return_value = error_mark_node;
   /* And signal caller that TREE_NO_WARNING should be set on the
 RETURN_EXPR to avoid control reaches end of non-void function
 warnings in tree-cfg.cc.  */
@@ -11449,7 +11451,11 @@ check_return_expr (tree retval, bool *no_warning, bool 
*dangling)
 
   /* If the conversion failed, treat this just like `return;'.  */
   if (retval == error_mark_node)
-   return retval;
+   {
+ /* And suppress NRV.  */
+ current_function_return_value = error_mark_node;
+ return retval;
+   }
   /* We can't initialize a register from a AGGR_INIT_EXPR.  */
   else if (! cfun->returns_struct
   && TREE_CODE (retval) == TARGET_EXPR
diff --git a/gcc/testsuite/g++.dg/parse/crash78.C 
b/gcc/testsuite/g++.dg/parse/crash78.C
new file mode 100644
index ..f30fe08df54b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash78.C
@@ -0,0 +1,15 @@
+// PR c++/117099
+// { dg-do "compile" }
+
+struct X {
+  ~X();
+};
+
+X test(bool b) {
+  {
+X x;
+return x;
+  }
+  return X();
+  if (!(b)) return; // { dg-error "return-statement with no value" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash78a.C 
b/gcc/testsuite/g++.dg/parse/crash78a.C
new file mode 100644
index ..241a5e390dee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash78a.C
@@ -0,0 +1,22 @@
+// PR c++/117099
+// With -fpermissive, make sure we don't do NRV in this case, but keep
+// executing fine. Note that the return at line 16 is undefined behaviour.
+// { dg-do "run" }
+// { dg-options "-fpermissive" }
+
+struct X {
+  ~X() {}
+};
+
+X test(bool b) {
+  X x;
+  if (b)
+return x;
+  else
+return; // { dg-warning "return-statement with no value" }
+}
+
+int main(int, char*[]) {
+  (void) test (false);
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash79.C 
b/gcc/testsuite/g++.dg/parse/crash79.C
new file mode 100644
index ..08d62af39c62
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash79.C
@@ -0,0 +1,15 @@
+// PR c++/117129
+// { dg-do "compile" { target c++11 } }
+
+struct Noncopyable {
+  Noncopyable();
+  Noncopyable(const Noncopyable &) = delete; // { dg-note "declared here" }
+  virtual ~Noncopyable();
+};
+Noncopyable nrvo() { 
+  {
+Noncopyable A;
+return A; // { dg-error "use of deleted function" }
+ // { dg-note "display considered" "" { target *-*-* } .-1 }
+  }
+}


[gcc r14-10888] testsuite: arm: Use effective-target for pr98636.c test

2024-11-05 Thread Torbjorn Svensson via Gcc-cvs
https://gcc.gnu.org/g:232d539f25b35903db301e94270541baf063f157

commit r14-10888-g232d539f25b35903db301e94270541baf063f157
Author: Torbjörn SVENSSON 
Date:   Fri Nov 1 11:11:26 2024 +0100

testsuite: arm: Use effective-target for pr98636.c test

The test case assumes that -mfp16-format=alternative is accepted for the
target, but not all targets support this flag. One such target is
Cortex-M85 that does support FP16, but not the alternative format.

gcc/testsuite/ChangeLog:

* gcc.target/arm/pr98636.c: Use effective-target
arm_fp16_alternative.

Signed-off-by: Torbjörn SVENSSON 
(cherry picked from commit 4602f628f723688a10c14ab20bd013ba7a825dab)

Diff:
---
 gcc/testsuite/gcc.target/arm/pr98636.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/arm/pr98636.c 
b/gcc/testsuite/gcc.target/arm/pr98636.c
index 559f9a26c1ec..28f05322156a 100644
--- a/gcc/testsuite/gcc.target/arm/pr98636.c
+++ b/gcc/testsuite/gcc.target/arm/pr98636.c
@@ -1,6 +1,8 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_softfp_ok } */
-/* { dg-options "-mfp16-format=alternative -mfloat-abi=softfp" } */
+/* { dg-require-effective-target arm_fp16_alternative_ok } */
+/* { dg-options "-mfloat-abi=softfp" } */
+/* { dg-add-options arm_fp16_alternative } */
 
 #pragma GCC push_options
 # pragma GCC target ("arch=armv8.2-a+fp16") /* { dg-error "selected fp16 
options are incompatible" } */


[gcc r15-4966] testsuite: arm: Relax register selection [PR116623]

2024-11-05 Thread Torbjorn Svensson via Gcc-cvs
https://gcc.gnu.org/g:e152a734337a06ed085c2e6700f21cda9ca7ad17

commit r15-4966-ge152a734337a06ed085c2e6700f21cda9ca7ad17
Author: Torbjörn SVENSSON 
Date:   Sat Oct 19 18:08:01 2024 +0200

testsuite: arm: Relax register selection [PR116623]

Since r15-1619-g3b9b8d6cfdf, test5 and test8 fails due to that "ip"
might be used and r3 might be moved to another register for later
dereference.

gcc/testsuite/ChangeLog:

PR testsuite/116623
* gcc.target/arm/mve/dlstp-compile-asm-2.c: Align test5 and
test8 with changes in r15-1619-g3b9b8d6cfdf.

Signed-off-by: Torbjörn SVENSSON 

Diff:
---
 gcc/testsuite/gcc.target/arm/mve/dlstp-compile-asm-2.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/dlstp-compile-asm-2.c 
b/gcc/testsuite/gcc.target/arm/mve/dlstp-compile-asm-2.c
index 84f4a2fc4f9b..c62f592a60dd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/dlstp-compile-asm-2.c
+++ b/gcc/testsuite/gcc.target/arm/mve/dlstp-compile-asm-2.c
@@ -147,15 +147,17 @@ void test5 (uint8_t *a, uint8_t *b, uint8_t *c,  uint8_t 
*d, int n)
 /*
 ** test5:
 **...
-** dlstp.8 lr, r[0-9]+
+** (?:mov  (r[0-9]+), r3)?
+**...
+** dlstp.8 lr, (?:r[0-9]+|ip)
 **...
 ** vldrb.8 q[0-9]+, \[r1\]
 ** vldrb.8 q[0-9]+, \[r2\]
 **...
 ** vadd.i8 (q[0-9]+), q[0-9]+, q[0-9]+
 **...
-** vstrb.8 \1, \[r2\]
-** vstrb.8 \1, \[r3\]
+** vstrb.8 \2, \[r2\]
+** vstrb.8 \2, \[(r3|\1)\]
 ** letplr, .*
 **...
 */
@@ -247,7 +249,7 @@ void test8 (int32_t *a, int32_t *b, int32_t *c, int n, int 
g)
 **...
 ** dlstp.32lr, r3
 ** vldrw.32q[0-9]+, \[r0\], #16
-** vctp.32 r4
+** vctp.32 (?:r4|ip)
 ** vpst
 ** vldrwt.32   q[0-9]+, \[r1\], #16
 **...


[gcc r15-4964] c: gimplefe: Only allow an identifier before ? [PR117445]

2024-11-05 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:3621d2ac22b75b154c2964c0db84b58be427f3a8

commit r15-4964-g3621d2ac22b75b154c2964c0db84b58be427f3a8
Author: Andrew Pinski 
Date:   Mon Nov 4 23:42:29 2024 -0800

c: gimplefe: Only allow an identifier before ? [PR117445]

Since r13-707-g68e0063397ba82, COND_EXPR/VEC_COND_EXPR has not
allowed a comparison as the first operand but the gimple front-end
was not updated for this change and you would error out later on.
An assert was added with r15-4791-gb60031e8f9f8fe which meant an ICE
would happen from the gimple FE.
This removes support for parsing of the `?:` expressions except for an
identifier.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/c/ChangeLog:

PR c/117445
* gimple-parser.cc (c_parser_gimple_statement): Remove
support for comparisons before the querry (`?`) token.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/c/gimple-parser.cc | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index 8d505084a8af..7e445ce2ff8f 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -880,11 +880,9 @@ c_parser_gimple_statement (gimple_parser &parser, 
gimple_seq *seq)
   if (lhs.value != error_mark_node
   && rhs.value != error_mark_node)
 {
-  /* If we parsed a comparison or an identifier and the next token
-is a '?' then parse a conditional expression.  */
-  if ((COMPARISON_CLASS_P (rhs.value)
-  || SSA_VAR_P (rhs.value))
- && c_parser_next_token_is (parser, CPP_QUERY))
+  /* If we parsed an identifier and the next token  is a '?' then parse
+a conditional expression.  */
+  if (SSA_VAR_P (rhs.value) && c_parser_next_token_is (parser, CPP_QUERY))
{
  struct c_expr trueval, falseval;
  c_parser_consume_token (parser);


[gcc r15-4965] testsuite: arm: Use effective-target for pr98636.c test

2024-11-05 Thread Torbjorn Svensson via Gcc-cvs
https://gcc.gnu.org/g:4602f628f723688a10c14ab20bd013ba7a825dab

commit r15-4965-g4602f628f723688a10c14ab20bd013ba7a825dab
Author: Torbjörn SVENSSON 
Date:   Fri Nov 1 11:11:26 2024 +0100

testsuite: arm: Use effective-target for pr98636.c test

The test case assumes that -mfp16-format=alternative is accepted for the
target, but not all targets support this flag. One such target is
Cortex-M85 that does support FP16, but not the alternative format.

gcc/testsuite/ChangeLog:

* gcc.target/arm/pr98636.c: Use effective-target
arm_fp16_alternative.

Signed-off-by: Torbjörn SVENSSON 

Diff:
---
 gcc/testsuite/gcc.target/arm/pr98636.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/arm/pr98636.c 
b/gcc/testsuite/gcc.target/arm/pr98636.c
index 559f9a26c1ec..28f05322156a 100644
--- a/gcc/testsuite/gcc.target/arm/pr98636.c
+++ b/gcc/testsuite/gcc.target/arm/pr98636.c
@@ -1,6 +1,8 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_softfp_ok } */
-/* { dg-options "-mfp16-format=alternative -mfloat-abi=softfp" } */
+/* { dg-require-effective-target arm_fp16_alternative_ok } */
+/* { dg-options "-mfloat-abi=softfp" } */
+/* { dg-add-options arm_fp16_alternative } */
 
 #pragma GCC push_options
 # pragma GCC target ("arch=armv8.2-a+fp16") /* { dg-error "selected fp16 
options are incompatible" } */


[gcc r14-10889] testsuite: arm: Use effective-target for pr68620 and pr78041 tests

2024-11-05 Thread Torbjorn Svensson via Gcc-cvs
https://gcc.gnu.org/g:f23a894f3b5ea42f16c996c76130e0494b17

commit r14-10889-gf23a894f3b5ea42f16c996c76130e0494b17
Author: Torbjörn SVENSSON 
Date:   Thu Oct 31 19:00:36 2024 +0100

testsuite: arm: Use effective-target for pr68620 and pr78041 tests

gcc/testsuite/ChangeLog:

* gcc.target/arm/pr68620.c: Use effective-target arm_neon.
* gcc.target/arm/pr78041.c: Use effective-target arm_arch_v7a.

Signed-off-by: Torbjörn SVENSSON 
(cherry picked from commit c7518891483e2aa558390ffeab4a19ba747814d6)

Diff:
---
 gcc/testsuite/gcc.target/arm/pr68620.c | 6 +++---
 gcc/testsuite/gcc.target/arm/pr78041.c | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/pr68620.c 
b/gcc/testsuite/gcc.target/arm/pr68620.c
index 91878432b005..6e38671752f2 100644
--- a/gcc/testsuite/gcc.target/arm/pr68620.c
+++ b/gcc/testsuite/gcc.target/arm/pr68620.c
@@ -1,8 +1,8 @@
 /* { dg-do compile } */
 /* { dg-skip-if "-mpure-code supports M-profile without Neon only" { *-*-* } { 
"-mpure-code" } } */
-/* { dg-require-effective-target arm_fp_ok } */
-/* { dg-options "-mfp16-format=ieee" } */
-/* { dg-add-options arm_fp } */
+/* { dg-require-effective-target arm_arch_v7a_ok } */
+/* { dg-options "-mfp16-format=ieee -mfpu=auto -mfloat-abi=softfp" } */
+/* { dg-add-options arm_arch_v7a } */
 
 #include "arm_neon.h"
 
diff --git a/gcc/testsuite/gcc.target/arm/pr78041.c 
b/gcc/testsuite/gcc.target/arm/pr78041.c
index 340ab5cb433b..418b7e09fc44 100644
--- a/gcc/testsuite/gcc.target/arm/pr78041.c
+++ b/gcc/testsuite/gcc.target/arm/pr78041.c
@@ -1,6 +1,7 @@
 /* { dg-require-effective-target arm_thumb2_ok } */
 /* { dg-require-effective-target arm_neon_ok } */
-/* { dg-options "-fno-inline -mthumb -O1 -mfpu=neon -w" } */
+/* { dg-options "-fno-inline -mthumb -O1 -w" } */
+/* { dg-add-options arm_neon } */
 
 extern void abort (void);


[gcc r15-4967] testsuite: arm: Use effective-target for pr68620 and pr78041 tests

2024-11-05 Thread Torbjorn Svensson via Gcc-cvs
https://gcc.gnu.org/g:c7518891483e2aa558390ffeab4a19ba747814d6

commit r15-4967-gc7518891483e2aa558390ffeab4a19ba747814d6
Author: Torbjörn SVENSSON 
Date:   Thu Oct 31 19:00:36 2024 +0100

testsuite: arm: Use effective-target for pr68620 and pr78041 tests

gcc/testsuite/ChangeLog:

* gcc.target/arm/pr68620.c: Use effective-target arm_neon.
* gcc.target/arm/pr78041.c: Use effective-target arm_arch_v7a.

Signed-off-by: Torbjörn SVENSSON 

Diff:
---
 gcc/testsuite/gcc.target/arm/pr68620.c | 6 +++---
 gcc/testsuite/gcc.target/arm/pr78041.c | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/pr68620.c 
b/gcc/testsuite/gcc.target/arm/pr68620.c
index 91878432b005..6e38671752f2 100644
--- a/gcc/testsuite/gcc.target/arm/pr68620.c
+++ b/gcc/testsuite/gcc.target/arm/pr68620.c
@@ -1,8 +1,8 @@
 /* { dg-do compile } */
 /* { dg-skip-if "-mpure-code supports M-profile without Neon only" { *-*-* } { 
"-mpure-code" } } */
-/* { dg-require-effective-target arm_fp_ok } */
-/* { dg-options "-mfp16-format=ieee" } */
-/* { dg-add-options arm_fp } */
+/* { dg-require-effective-target arm_arch_v7a_ok } */
+/* { dg-options "-mfp16-format=ieee -mfpu=auto -mfloat-abi=softfp" } */
+/* { dg-add-options arm_arch_v7a } */
 
 #include "arm_neon.h"
 
diff --git a/gcc/testsuite/gcc.target/arm/pr78041.c 
b/gcc/testsuite/gcc.target/arm/pr78041.c
index 340ab5cb433b..418b7e09fc44 100644
--- a/gcc/testsuite/gcc.target/arm/pr78041.c
+++ b/gcc/testsuite/gcc.target/arm/pr78041.c
@@ -1,6 +1,7 @@
 /* { dg-require-effective-target arm_thumb2_ok } */
 /* { dg-require-effective-target arm_neon_ok } */
-/* { dg-options "-fno-inline -mthumb -O1 -mfpu=neon -w" } */
+/* { dg-options "-fno-inline -mthumb -O1 -w" } */
+/* { dg-add-options arm_neon } */
 
 extern void abort (void);


[gcc r12-10804] c++: Defer -fstrong-eval-order processing to template instantiation time [PR117158]

2024-11-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:5fdd38d576c20d5a337b5c7d14108981d0751434

commit r12-10804-g5fdd38d576c20d5a337b5c7d14108981d0751434
Author: Simon Martin 
Date:   Tue Nov 5 10:07:42 2024 +0100

c++: Defer -fstrong-eval-order processing to template instantiation time 
[PR117158]

Since r10-3793-g1a37b6d9a7e57c, we ICE upon the following valid code
with -std=c++17 and above

=== cut here ===
struct Base {
  unsigned int *intarray;
};
template  struct Sub : public Base {
  bool Get(int i) {
return (Base::intarray[++i] == 0);
  }
};
=== cut here ===

The problem is that from c++17 on, we use -fstrong-eval-order and need
to wrap the array access expression into a SAVE_EXPR. We do so at
template declaration time, and end up calling contains_placeholder_p
with a SCOPE_REF, that it does not handle well.

This patch fixes this by deferring the wrapping into SAVE_EXPR to
instantiation time for templates, when the SCOPE_REF will have been
turned into a COMPONENT_REF.

PR c++/117158

gcc/cp/ChangeLog:

* typeck.cc (cp_build_array_ref): Only wrap array expression
into a SAVE_EXPR at template instantiation time.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/eval-order13.C: New test.
* g++.dg/parse/crash77.C: New test.

(cherry picked from commit b1d92aeb8583c8d1491c97703680c5fb88ed1fe4)

Diff:
---
 gcc/cp/typeck.cc  |  3 ++-
 gcc/testsuite/g++.dg/cpp1z/eval-order13.C | 29 +
 gcc/testsuite/g++.dg/parse/crash77.C  | 13 +
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index ff8f0ef00838..df819701d4a6 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -3919,7 +3919,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 tree ar = cp_default_conversion (array, complain);
 tree ind = cp_default_conversion (idx, complain);
 
-if (!first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
+if (!processing_template_decl
+   && !first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
   ar = first = save_expr (ar);
 
 /* Put the integer in IND to simplify error checking.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/eval-order13.C 
b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
new file mode 100644
index ..6e8ebeb30967
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
@@ -0,0 +1,29 @@
+// PR c++/117158 - Similar to eval-order7.C, only with templates.
+// { dg-do run { target c++11 } }
+// { dg-options "-fstrong-eval-order" }
+
+int a[4] = { 1, 2, 3, 4 };
+int b[4] = { 5, 6, 7, 8 };
+
+struct Base {
+  int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  int Get(int i) {
+Base::intarray = a;
+int r = Base::intarray[(Base::intarray = b, i)];
+if (Base::intarray != b)
+  __builtin_abort ();
+return r;
+  }
+};
+
+int
+main ()
+{
+  Sub s;
+  if (s.Get (3) != 4)
+__builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C 
b/gcc/testsuite/g++.dg/parse/crash77.C
new file mode 100644
index ..729362eb5991
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash77.C
@@ -0,0 +1,13 @@
+// PR c++/117158
+// { dg-do "compile" }
+
+struct Base {
+  unsigned int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  bool Get(int i) {
+return (Base::intarray[++i] == 0);
+  }
+};


[gcc r13-9171] Fortran: Fix regressions with intent(out) class[PR115070, PR115348].

2024-11-05 Thread Paul Thomas via Gcc-cvs
https://gcc.gnu.org/g:43522516e5a5c95807a1bf31c3d11014fb1ffb77

commit r13-9171-g43522516e5a5c95807a1bf31c3d11014fb1ffb77
Author: Paul Thomas 
Date:   Tue Nov 5 21:09:26 2024 +

Fortran: Fix regressions with intent(out) class[PR115070, PR115348].

2024-11-05  Paul Thomas  

gcc/fortran
PR fortran/115070
PR fortran/115348
* trans-expr.cc (gfc_trans_class_init_assign): If all the
components of the default initializer are null for a scalar,
build an empty statement to prevent prior declarations from
disappearing.

gcc/testsuite/
PR fortran/115070
* gfortran.dg/ieee/pr115070.f90: New test.

PR fortran/115348
* gfortran.dg/pr115348.f90: New test.

Diff:
---
 gcc/fortran/trans-expr.cc   |  6 -
 gcc/testsuite/gfortran.dg/ieee/pr115070.f90 | 28 +++
 gcc/testsuite/gfortran.dg/pr115348.f90  | 35 +
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 46348d7df456..59a7ff8d8d06 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -1722,7 +1722,11 @@ gfc_trans_class_init_assign (gfc_code *code)
  if (cmp->initializer)
break;
  else if (!cmp->next)
-   return build_empty_stmt (input_location);
+   {
+ tmp = build_empty_stmt (input_location);
+ gfc_add_expr_to_block (&block, tmp);
+ return gfc_finish_block (&block);
+   }
}
 }
 
diff --git a/gcc/testsuite/gfortran.dg/ieee/pr115070.f90 
b/gcc/testsuite/gfortran.dg/ieee/pr115070.f90
new file mode 100644
index ..9378f770e2c6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ieee/pr115070.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+!
+! Test the fix for PR115070
+!
+! Contributed by Sebastien Bardeau  
+!
+module my_mod
+  type my_type
+integer :: a
+  contains
+final :: myfinal
+  end type my_type
+contains
+  subroutine my_sub(obs)
+use ieee_arithmetic
+class(my_type), intent(out) :: obs
+  end subroutine my_sub
+  subroutine myfinal (arg)
+type (my_type) :: arg
+print *, arg%a
+  end
+end module my_mod
+
+  use my_mod
+  type (my_type) :: z
+  z%a = 42
+  call my_sub (z)
+end
diff --git a/gcc/testsuite/gfortran.dg/pr115348.f90 
b/gcc/testsuite/gfortran.dg/pr115348.f90
new file mode 100644
index ..bc644b2f1c0c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr115348.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-fcheck=recursion" }
+!
+! Test the fix for pr115348.
+!
+! Contributed by Maxime van den Bossche  
+!
+module mymodule
+implicit none
+
+type mytype
+integer :: mynumber
+contains
+procedure :: myroutine
+end type mytype
+
+contains
+
+subroutine myroutine(self)
+class(mytype), intent(out) :: self
+
+self%mynumber = 1
+end subroutine myroutine
+end module mymodule
+
+
+program myprogram
+use mymodule, only: mytype
+implicit none
+
+type(mytype) :: myobject
+
+call myobject%myroutine()
+print *, myobject%mynumber
+end program myprogram


[gcc r14-10890] c++: reference variable as default targ [PR101463]

2024-11-05 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:124f2f62e01c6f110279608ad09e0f1d378e4899

commit r14-10890-g124f2f62e01c6f110279608ad09e0f1d378e4899
Author: Patrick Palka 
Date:   Tue Nov 5 15:18:26 2024 -0500

c++: reference variable as default targ [PR101463]

Here during default template argument substitution we wrongly consider
the (substituted) default arguments v and vt as value-dependent
which ultimately leads to deduction failure for the calls.

The bogus value_dependent_expression_p result aside, I noticed
type_unification_real during default targ substitution keeps track of
whether all previous targs are known and non-dependent, as is the case
for these calls.  And in such cases it should be safe to avoid checking
dependence of the substituted default targ and just assume it's not.
This patch implements this optimization for GCC 14, which lets us accept
both testcases by sidestepping the value_dependent_expression_p issue
altogether.  (Note that for GCC 15 we fixed this differently, see
r15-3038-g5348e3cb9bc99d.)

PR c++/101463

gcc/cp/ChangeLog:

* pt.cc (type_unification_real): Avoid checking dependence of
a substituted default template argument if we can assume it's
non-dependent.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/nontype6.C: New test.
* g++.dg/cpp1z/nontype6a.C: New test.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/pt.cc   |  4 +++-
 gcc/testsuite/g++.dg/cpp1z/nontype6.C  | 24 
 gcc/testsuite/g++.dg/cpp1z/nontype6a.C | 25 +
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 818d5b65edce..4f83426fb56c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -23651,12 +23651,14 @@ type_unification_real (tree tparms,
/* We replaced all the tparms, substitute again out of
   template context.  */
substed = NULL_TREE;
+ else
+   processing_template_decl = 1;
}
  if (!substed)
substed = tsubst_template_arg (arg, full_targs, complain,
   NULL_TREE);
 
- if (!uses_template_parms (substed))
+ if (!processing_template_decl || !uses_template_parms (substed))
arg = convert_template_argument (parm, substed, full_targs,
 complain, i, NULL_TREE);
  else if (saw_undeduced == 1)
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype6.C 
b/gcc/testsuite/g++.dg/cpp1z/nontype6.C
new file mode 100644
index ..06cd234cc61a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype6.C
@@ -0,0 +1,24 @@
+// PR c++/101463
+// { dg-do compile { target c++17 } }
+
+int a;
+
+int& v = a;
+
+template
+void f(int) { }
+
+template
+void g(T) { }
+
+template
+int& vt = a;
+
+template>
+void h(T) { }
+
+int main() {
+  f(0);
+  g(0);
+  h(0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype6a.C 
b/gcc/testsuite/g++.dg/cpp1z/nontype6a.C
new file mode 100644
index ..8bc40a0505c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype6a.C
@@ -0,0 +1,25 @@
+// PR c++/101463
+// A version of nontype6.C where v and vt are constexpr.
+// { dg-do compile { target c++17 } }
+
+int a;
+
+constexpr int& v = a;
+
+template
+void f(int) { }
+
+template
+void g(T) { }
+
+template
+constexpr int& vt = a;
+
+template>
+void h(T) { }
+
+int main() {
+  f(0);
+  g(0);
+  h(0);
+}


[gcc r15-4969] fortran: dynamically allocate error_buffer [PR117442]

2024-11-05 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:8c4184682d1cdfc43296f9550a48eaadb7501bbd

commit r15-4969-g8c4184682d1cdfc43296f9550a48eaadb7501bbd
Author: David Malcolm 
Date:   Tue Nov 5 18:30:39 2024 -0500

fortran: dynamically allocate error_buffer [PR117442]

PR fortran/117442 reports a crash on exit of f951 when configured
with --enable-gather-detailed-mem-stats.

The crash happens if any diagnostics were ever buffered into
error_buffer.  The root cause is that error_buffer is statically
allocated and thus has a non-trivial destructor called at exit.
If error_buffer's diagnostic_buffer ever buffered anything, then
a diagnostic_per_format_buffer will have been created for the
buffer per-output-sink, and the destructors for these call
into the mem-stats subsystem, which has already beeen cleaned up.

The simplest fix is to allocate error_buffer on the heap, rather
that statically, which fixes the crash.

There's a comment about error_buffer:

  /* pp_error_buffer is statically allocated.  This simplifies memory
 management when using gfc_push/pop_error. */

added by Manu in r6-1748-g5862c189c2c3c2 while fixing PR fortran/66528.
The comment appears to be out of date.  I've tested maxerrors.f90 under
valgrind, and it's clean with the patch.

gcc/fortran/ChangeLog:
PR fortran/117442
* error.cc (error_buffer): Convert to a pointer so it can be
heap-allocated.
(gfc_error_now): Update for error_buffer being heap-allocated.
(gfc_clear_error): Likewise.
(gfc_error_flag_test): Likewise.
(gfc_error_check): Likewise.
(gfc_push_error): Likewise.
(gfc_pop_error): Likewise.
(gfc_diagnostics_init): Allocate error_buffer on the heap, rather
than statically.
(gfc_diagnostics_finish): Delete error_buffer.

Signed-off-by: David Malcolm 

Diff:
---
 gcc/fortran/error.cc | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/error.cc b/gcc/fortran/error.cc
index 050a8f286efd..1445ebcbecd8 100644
--- a/gcc/fortran/error.cc
+++ b/gcc/fortran/error.cc
@@ -43,7 +43,7 @@ static bool warnings_not_errors = false;
 /* True if the error/warnings should be buffered.  */
 static bool buffered_p;
 
-static gfc_error_buffer error_buffer;
+static gfc_error_buffer *error_buffer;
 static diagnostic_buffer *pp_error_buffer, *pp_warning_buffer;
 
 gfc_error_buffer::gfc_error_buffer ()
@@ -707,7 +707,7 @@ gfc_error_now (const char *gmsgid, ...)
   diagnostic_info diagnostic;
   rich_location rich_loc (line_table, UNKNOWN_LOCATION);
 
-  error_buffer.flag = true;
+  error_buffer->flag = true;
 
   va_start (argp, gmsgid);
   diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ERROR);
@@ -842,7 +842,7 @@ gfc_internal_error (const char *gmsgid, ...)
 void
 gfc_clear_error (void)
 {
-  error_buffer.flag = false;
+  error_buffer->flag = false;
   warnings_not_errors = false;
   gfc_clear_diagnostic_buffer (pp_error_buffer);
 }
@@ -853,7 +853,7 @@ gfc_clear_error (void)
 bool
 gfc_error_flag_test (void)
 {
-  return (error_buffer.flag
+  return (error_buffer->flag
  || !pp_error_buffer->empty_p ());
 }
 
@@ -864,10 +864,10 @@ gfc_error_flag_test (void)
 bool
 gfc_error_check (void)
 {
-  if (error_buffer.flag
+  if (error_buffer->flag
   || ! pp_error_buffer->empty_p ())
 {
-  error_buffer.flag = false;
+  error_buffer->flag = false;
   global_dc->flush_diagnostic_buffer (*pp_error_buffer);
   return true;
 }
@@ -903,7 +903,7 @@ gfc_move_error_buffer_from_to (gfc_error_buffer * 
buffer_from,
 void
 gfc_push_error (gfc_error_buffer *err)
 {
-  gfc_move_error_buffer_from_to (&error_buffer, err);
+  gfc_move_error_buffer_from_to (error_buffer, err);
 }
 
 
@@ -912,7 +912,7 @@ gfc_push_error (gfc_error_buffer *err)
 void
 gfc_pop_error (gfc_error_buffer *err)
 {
-  gfc_move_error_buffer_from_to (err, &error_buffer);
+  gfc_move_error_buffer_from_to (err, error_buffer);
 }
 
 
@@ -955,9 +955,8 @@ gfc_diagnostics_init (void)
   global_dc->m_source_printing.caret_chars[0] = '1';
   global_dc->m_source_printing.caret_chars[1] = '2';
   pp_warning_buffer = new diagnostic_buffer (*global_dc);
-  /* pp_error_buffer is statically allocated.  This simplifies memory
- management when using gfc_push/pop_error. */
-  pp_error_buffer = &(error_buffer.buffer);
+  error_buffer = new gfc_error_buffer ();
+  pp_error_buffer = &(error_buffer->buffer);
 }
 
 void
@@ -970,4 +969,7 @@ gfc_diagnostics_finish (void)
   diagnostic_text_finalizer (global_dc) = gfc_diagnostic_text_finalizer;
   global_dc->m_source_printing.caret_chars[0] = '^';
   global_dc->m_source_printing.caret_chars[1] = '^';
+  delete error_buffer;
+  error_buffer = nullptr;
+  pp_error_buffer = nullptr;
 }


[gcc r15-4968] match: Fix comment for `X != 0 ? X + ~0 : 0` transformation

2024-11-05 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:2e35fbd1fd1c8c149ce1156f4a2c15c9c331a1ca

commit r15-4968-g2e35fbd1fd1c8c149ce1156f4a2c15c9c331a1ca
Author: Andrew Pinski 
Date:   Sun Nov 3 12:19:46 2024 -0800

match: Fix comment for `X != 0 ? X + ~0 : 0` transformation

Just a small coment fix, the `(` was in the wrong location,
making it look it was transforming into `(X - X) != 0`
rather than `X - (X != 0)`.

Pushed as obvious after a quick build for x86_64-linux-gnu.

gcc/ChangeLog:

* match.pd (X != 0 ? X + ~0 : 0): Fix comment.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/match.pd | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 9107e6a95ca7..c10bf9a7b804 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3393,7 +3393,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 
 /* The boundary condition for case 10: IMM = 1:
SAT_U_SUB = X >= IMM ? (X - IMM) : 0.
-   simplify (X != 0 ? X + ~0 : 0) to (X - X != 0).  */
+   simplify (X != 0 ? X + ~0 : 0) to X - (X != 0).  */
 (simplify
  (cond (ne@1 @0 integer_zerop)
(nop_convert1? (plus (nop_convert2?@2 @0) integer_all_onesp))


[gcc r15-4973] i386: Add OPTION_MASK_ISA2_EVEX512 for some AVX512 instructions.

2024-11-05 Thread Hu via Gcc-cvs
https://gcc.gnu.org/g:8ac694ae67e24a798dce368587bed4c40b90fbc0

commit r15-4973-g8ac694ae67e24a798dce368587bed4c40b90fbc0
Author: Hu, Lin1 
Date:   Tue Nov 5 15:49:57 2024 +0800

i386: Add OPTION_MASK_ISA2_EVEX512 for some AVX512 instructions.

gcc/ChangeLog:

PR target/117304
* config/i386/i386-builtin.def: Add OPTION_MASK_ISA2_EVEX512 for 
some
AVX512 512-bits instructions.

gcc/testsuite/ChangeLog:

PR target/117304
* gcc.target/i386/pr117304-1.c: New test.

Diff:
---
 gcc/config/i386/i386-builtin.def   | 10 +-
 gcc/testsuite/gcc.target/i386/pr117304-1.c | 28 
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index c484e6dc29e4..26c23780b1c6 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -3357,11 +3357,11 @@ BDESC (OPTION_MASK_ISA_AVX512F, 0, 
CODE_FOR_sse_cvtsi2ss_round, "__builtin_ia32_
 BDESC (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_64BIT, 0, 
CODE_FOR_sse_cvtsi2ssq_round, "__builtin_ia32_cvtsi2ss64", 
IX86_BUILTIN_CVTSI2SS64, UNKNOWN, (int) V4SF_FTYPE_V4SF_INT64_INT)
 BDESC (OPTION_MASK_ISA_AVX512F, 0, CODE_FOR_sse2_cvtss2sd_round, 
"__builtin_ia32_cvtss2sd_round", IX86_BUILTIN_CVTSS2SD_ROUND, UNKNOWN, (int) 
V2DF_FTYPE_V2DF_V4SF_INT)
 BDESC (OPTION_MASK_ISA_AVX512F, 0, CODE_FOR_sse2_cvtss2sd_mask_round, 
"__builtin_ia32_cvtss2sd_mask_round", IX86_BUILTIN_CVTSS2SD_MASK_ROUND, 
UNKNOWN, (int) V2DF_FTYPE_V2DF_V4SF_V2DF_UQI_INT)
-BDESC (OPTION_MASK_ISA_AVX512F, 0, 
CODE_FOR_unspec_fix_truncv8dfv8si2_mask_round, 
"__builtin_ia32_cvttpd2dq512_mask", IX86_BUILTIN_CVTTPD2DQ512, UNKNOWN, (int) 
V8SI_FTYPE_V8DF_V8SI_QI_INT)
-BDESC (OPTION_MASK_ISA_AVX512F, 0, 
CODE_FOR_unspec_fixuns_truncv8dfv8si2_mask_round, 
"__builtin_ia32_cvttpd2udq512_mask", IX86_BUILTIN_CVTTPD2UDQ512, UNKNOWN, (int) 
V8SI_FTYPE_V8DF_V8SI_QI_INT)
-BDESC (OPTION_MASK_ISA_AVX512F, 0, 
CODE_FOR_unspec_fix_truncv16sfv16si2_mask_round, 
"__builtin_ia32_cvttps2dq512_mask", IX86_BUILTIN_CVTTPS2DQ512, UNKNOWN, (int) 
V16SI_FTYPE_V16SF_V16SI_HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512F, 0, 
CODE_FOR_unspec_fixuns_truncv16sfv16si2_mask_round, 
"__builtin_ia32_cvttps2udq512_mask", IX86_BUILTIN_CVTTPS2UDQ512, UNKNOWN, (int) 
V16SI_FTYPE_V16SF_V16SI_HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512F, 0, CODE_FOR_floatunsv16siv16sf2_mask_round, 
"__builtin_ia32_cvtudq2ps512_mask", IX86_BUILTIN_CVTUDQ2PS512, UNKNOWN, (int) 
V16SF_FTYPE_V16SI_V16SF_HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512, 
CODE_FOR_unspec_fix_truncv8dfv8si2_mask_round, 
"__builtin_ia32_cvttpd2dq512_mask", IX86_BUILTIN_CVTTPD2DQ512, UNKNOWN, (int) 
V8SI_FTYPE_V8DF_V8SI_QI_INT)
+BDESC (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512, 
CODE_FOR_unspec_fixuns_truncv8dfv8si2_mask_round, 
"__builtin_ia32_cvttpd2udq512_mask", IX86_BUILTIN_CVTTPD2UDQ512, UNKNOWN, (int) 
V8SI_FTYPE_V8DF_V8SI_QI_INT)
+BDESC (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512, 
CODE_FOR_unspec_fix_truncv16sfv16si2_mask_round, 
"__builtin_ia32_cvttps2dq512_mask", IX86_BUILTIN_CVTTPS2DQ512, UNKNOWN, (int) 
V16SI_FTYPE_V16SF_V16SI_HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512, 
CODE_FOR_unspec_fixuns_truncv16sfv16si2_mask_round, 
"__builtin_ia32_cvttps2udq512_mask", IX86_BUILTIN_CVTTPS2UDQ512, UNKNOWN, (int) 
V16SI_FTYPE_V16SF_V16SI_HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512, 
CODE_FOR_floatunsv16siv16sf2_mask_round, "__builtin_ia32_cvtudq2ps512_mask", 
IX86_BUILTIN_CVTUDQ2PS512, UNKNOWN, (int) V16SF_FTYPE_V16SI_V16SF_HI_INT)
 BDESC (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_64BIT, 0, 
CODE_FOR_cvtusi2sd64_round, "__builtin_ia32_cvtusi2sd64", 
IX86_BUILTIN_CVTUSI2SD64, UNKNOWN, (int) V2DF_FTYPE_V2DF_UINT64_INT)
 BDESC (OPTION_MASK_ISA_AVX512F, 0, CODE_FOR_cvtusi2ss32_round, 
"__builtin_ia32_cvtusi2ss32", IX86_BUILTIN_CVTUSI2SS32, UNKNOWN, (int) 
V4SF_FTYPE_V4SF_UINT_INT)
 BDESC (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_64BIT, 0, 
CODE_FOR_cvtusi2ss64_round, "__builtin_ia32_cvtusi2ss64", 
IX86_BUILTIN_CVTUSI2SS64, UNKNOWN, (int) V4SF_FTYPE_V4SF_UINT64_INT)
diff --git a/gcc/testsuite/gcc.target/i386/pr117304-1.c 
b/gcc/testsuite/gcc.target/i386/pr117304-1.c
new file mode 100644
index ..fc1c5bfd3e35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr117304-1.c
@@ -0,0 +1,28 @@
+/* PR target/117304 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512f -mno-evex512" } */
+
+typedef __attribute__((__vector_size__(32))) int __v8si;
+typedef __attribute__((__vector_size__(32))) unsigned int __v8su;
+typedef __attribute__((__vector_size__(64))) double __v8df;
+typedef __attribute__((__vector_size__(64))) int __v16si;
+typedef __attribute__((__vector_size__(64))) unsigned int __v16su;
+typedef __attribute__((__vector_size__(64))) float __v16sf;
+typedef float __m512 __attribute__ ((__vector_size__ (6

[gcc r15-4972] Intel MOVRS tests: Also scan (%e.x)

2024-11-05 Thread H.J. Lu via Gcc-cvs
https://gcc.gnu.org/g:d228a0729ff7d1f72f84bb910d765ead5706fed4

commit r15-4972-gd228a0729ff7d1f72f84bb910d765ead5706fed4
Author: H.J. Lu 
Date:   Wed Nov 6 08:14:04 2024 +0800

Intel MOVRS tests: Also scan (%e.x)

Since x32 uses (%reg32), instead of (%r.x), also scan (%e.x).

* gcc.target/i386/avx10_2-512-movrs-1.c: Also scan (%e.x).
* gcc.target/i386/avx10_2-movrs-1.c: Likewise.
* gcc.target/i386/movrs-1.c: Likewise.

Signed-off-by: H.J. Lu 

Diff:
---
 .../gcc.target/i386/avx10_2-512-movrs-1.c  | 24 +--
 gcc/testsuite/gcc.target/i386/avx10_2-movrs-1.c| 48 +++---
 gcc/testsuite/gcc.target/i386/movrs-1.c|  8 ++--
 3 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/gcc/testsuite/gcc.target/i386/avx10_2-512-movrs-1.c 
b/gcc/testsuite/gcc.target/i386/avx10_2-512-movrs-1.c
index 9166f2e41f4a..682b81278ae9 100644
--- a/gcc/testsuite/gcc.target/i386/avx10_2-512-movrs-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx10_2-512-movrs-1.c
@@ -1,17 +1,17 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-march=x86-64-v3 -mavx10.2-512 -mmovrs -O2" } */
-/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
-/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
-/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
-/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
-/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
-/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
-/* { dg-final { scan-assembler-times "vmovrsw\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "vmovrsw\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
-/* { dg-final { scan-assembler-times "vmovrsw\[ \\t\]\+\\(%r.x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
+/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
+/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
+/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
+/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
+/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
+/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
+/* { dg-final { scan-assembler-times "vmovrsw\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "vmovrsw\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}" 2 } } */
+/* { dg-final { scan-assembler-times "vmovrsw\[ \\t\]\+\\(%(?:r|e).x\\), 
%zmm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
 
 #include 
 
diff --git a/gcc/testsuite/gcc.target/i386/avx10_2-movrs-1.c 
b/gcc/testsuite/gcc.target/i386/avx10_2-movrs-1.c
index f8c2f309cd9c..f1c65efc051e 100644
--- a/gcc/testsuite/gcc.target/i386/avx10_2-movrs-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx10_2-movrs-1.c
@@ -1,29 +1,29 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-march=x86-64-v3 -mavx10.2 -mmovrs -O2" } */
-/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+{%k\[1-7\]}" 2 } } */
-/* { dg-final { scan-assembler-times "vmovrsb\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
-/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+{%k\[1-7\]}" 2 } } */
-/* { dg-final { scan-assembler-times "vmovrsd\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
-/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+{%k\[1-7\]}" 2 } } */
-/* { dg-final { scan-assembler-times "vmovrsq\[ \\t\]\+\\(%r.x\\), 
%ymm\[0-9\]+{%k\[1-7\]}{z}" 1 } } */
-/* { dg-final { scan-

[gcc r15-4971] gcc.target/i386/apx-ndd.c: Also scan (%edi)

2024-11-05 Thread H.J. Lu via Gcc-cvs
https://gcc.gnu.org/g:c4155653e6ffe05b032702e9de256893e0245284

commit r15-4971-gc4155653e6ffe05b032702e9de256893e0245284
Author: H.J. Lu 
Date:   Wed Nov 6 07:44:24 2024 +0800

gcc.target/i386/apx-ndd.c: Also scan (%edi)

Since x32 uses (%edi), instead of (%rdi), also scan (%edi).

* gcc.target/i386/apx-ndd.c: Also scan (%edi).

Signed-off-by: H.J. Lu 

Diff:
---
 gcc/testsuite/gcc.target/i386/apx-ndd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd.c 
b/gcc/testsuite/gcc.target/i386/apx-ndd.c
index 6c88aff911aa..ce77630a47c8 100644
--- a/gcc/testsuite/gcc.target/i386/apx-ndd.c
+++ b/gcc/testsuite/gcc.target/i386/apx-ndd.c
@@ -207,4 +207,4 @@ FOO2 (int64_t, imul, *)
 /* { dg-final { scan-assembler-times "ror(?:b|l|w|q)\[^\n\r]*1, 
%(?:|r|e)di(?:|l), %(?:|r|e)a(?:x|l)" 4 } } */
 /* { dg-final { scan-assembler-times "rol(?:b|l|w|q)\[^\n\r]*1, 
%(?:|r|e)di(?:|l), %(?:|r|e)a(?:x|l)" 4 } } */
 /* { dg-final { scan-assembler-times "imul(?:l|q)\[^\n\r]%(?:|r|e)(?:|s|d)i, 
%(?:r|e)(?:|s|d)i, %(?:|r|e)ax" 3 } } */
-/* { dg-final { scan-assembler-times "imul(?:l|w|q)\[^\n\r]\\(%rdi\\), 
%(?:|r|e)si, %(?:|r|e)ax" 3 } } */
+/* { dg-final { scan-assembler-times "imul(?:l|w|q)\[^\n\r]\\(%(?:r|e)di\\), 
%(?:|r|e)si, %(?:|r|e)ax" 3 } } */


[gcc r14-10892] c++: Defer -fstrong-eval-order processing to template instantiation time [PR117158]

2024-11-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:951daf54174b88e30feaf413a4de0c8388a06d9d

commit r14-10892-g951daf54174b88e30feaf413a4de0c8388a06d9d
Author: Simon Martin 
Date:   Wed Nov 6 06:54:57 2024 +0100

c++: Defer -fstrong-eval-order processing to template instantiation time 
[PR117158]

Since r10-3793-g1a37b6d9a7e57c, we ICE upon the following valid code
with -std=c++17 and above

=== cut here ===
struct Base {
  unsigned int *intarray;
};
template  struct Sub : public Base {
  bool Get(int i) {
return (Base::intarray[++i] == 0);
  }
};
=== cut here ===

The problem is that from c++17 on, we use -fstrong-eval-order and need
to wrap the array access expression into a SAVE_EXPR. We do so at
template declaration time, and end up calling contains_placeholder_p
with a SCOPE_REF, that it does not handle well.

This patch fixes this by deferring the wrapping into SAVE_EXPR to
instantiation time for templates, when the SCOPE_REF will have been
turned into a COMPONENT_REF.

PR c++/117158

gcc/cp/ChangeLog:

* typeck.cc (cp_build_array_ref): Only wrap array expression
into a SAVE_EXPR at template instantiation time.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/eval-order13.C: New test.
* g++.dg/parse/crash77.C: New test.

(cherry picked from commit b1d92aeb8583c8d1491c97703680c5fb88ed1fe4)

Diff:
---
 gcc/cp/typeck.cc  |  3 ++-
 gcc/testsuite/g++.dg/cpp1z/eval-order13.C | 29 +
 gcc/testsuite/g++.dg/parse/crash77.C  | 13 +
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index a72599bc1536..6ca2cee682c4 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4073,7 +4073,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 tree ar = cp_default_conversion (array, complain);
 tree ind = cp_default_conversion (idx, complain);
 
-if (!first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
+if (!processing_template_decl
+   && !first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
   ar = first = save_expr (ar);
 
 /* Put the integer in IND to simplify error checking.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/eval-order13.C 
b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
new file mode 100644
index ..6e8ebeb30967
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
@@ -0,0 +1,29 @@
+// PR c++/117158 - Similar to eval-order7.C, only with templates.
+// { dg-do run { target c++11 } }
+// { dg-options "-fstrong-eval-order" }
+
+int a[4] = { 1, 2, 3, 4 };
+int b[4] = { 5, 6, 7, 8 };
+
+struct Base {
+  int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  int Get(int i) {
+Base::intarray = a;
+int r = Base::intarray[(Base::intarray = b, i)];
+if (Base::intarray != b)
+  __builtin_abort ();
+return r;
+  }
+};
+
+int
+main ()
+{
+  Sub s;
+  if (s.Get (3) != 4)
+__builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C 
b/gcc/testsuite/g++.dg/parse/crash77.C
new file mode 100644
index ..729362eb5991
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash77.C
@@ -0,0 +1,13 @@
+// PR c++/117158
+// { dg-do "compile" }
+
+struct Base {
+  unsigned int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  bool Get(int i) {
+return (Base::intarray[++i] == 0);
+  }
+};


[gcc r13-9173] c++: Defer -fstrong-eval-order processing to template instantiation time [PR117158]

2024-11-05 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:75a5bc8c0143e7003ac19395317cc93b9a63c7d4

commit r13-9173-g75a5bc8c0143e7003ac19395317cc93b9a63c7d4
Author: Simon Martin 
Date:   Wed Nov 6 06:49:57 2024 +0100

c++: Defer -fstrong-eval-order processing to template instantiation time 
[PR117158]

Since r10-3793-g1a37b6d9a7e57c, we ICE upon the following valid code
with -std=c++17 and above

=== cut here ===
struct Base {
  unsigned int *intarray;
};
template  struct Sub : public Base {
  bool Get(int i) {
return (Base::intarray[++i] == 0);
  }
};
=== cut here ===

The problem is that from c++17 on, we use -fstrong-eval-order and need
to wrap the array access expression into a SAVE_EXPR. We do so at
template declaration time, and end up calling contains_placeholder_p
with a SCOPE_REF, that it does not handle well.

This patch fixes this by deferring the wrapping into SAVE_EXPR to
instantiation time for templates, when the SCOPE_REF will have been
turned into a COMPONENT_REF.

PR c++/117158

gcc/cp/ChangeLog:

* typeck.cc (cp_build_array_ref): Only wrap array expression
into a SAVE_EXPR at template instantiation time.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/eval-order13.C: New test.
* g++.dg/parse/crash77.C: New test.

(cherry picked from commit b1d92aeb8583c8d1491c97703680c5fb88ed1fe4)

Diff:
---
 gcc/cp/typeck.cc  |  3 ++-
 gcc/testsuite/g++.dg/cpp1z/eval-order13.C | 29 +
 gcc/testsuite/g++.dg/parse/crash77.C  | 13 +
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 2b29bdc4d70a..cbd8068c3a2a 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4076,7 +4076,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 tree ar = cp_default_conversion (array, complain);
 tree ind = cp_default_conversion (idx, complain);
 
-if (!first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
+if (!processing_template_decl
+   && !first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
   ar = first = save_expr (ar);
 
 /* Put the integer in IND to simplify error checking.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/eval-order13.C 
b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
new file mode 100644
index ..6e8ebeb30967
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/eval-order13.C
@@ -0,0 +1,29 @@
+// PR c++/117158 - Similar to eval-order7.C, only with templates.
+// { dg-do run { target c++11 } }
+// { dg-options "-fstrong-eval-order" }
+
+int a[4] = { 1, 2, 3, 4 };
+int b[4] = { 5, 6, 7, 8 };
+
+struct Base {
+  int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  int Get(int i) {
+Base::intarray = a;
+int r = Base::intarray[(Base::intarray = b, i)];
+if (Base::intarray != b)
+  __builtin_abort ();
+return r;
+  }
+};
+
+int
+main ()
+{
+  Sub s;
+  if (s.Get (3) != 4)
+__builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash77.C 
b/gcc/testsuite/g++.dg/parse/crash77.C
new file mode 100644
index ..729362eb5991
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash77.C
@@ -0,0 +1,13 @@
+// PR c++/117158
+// { dg-do "compile" }
+
+struct Base {
+  unsigned int *intarray;
+};
+
+template 
+struct Sub : public Base {
+  bool Get(int i) {
+return (Base::intarray[++i] == 0);
+  }
+};


[gcc r15-4974] Fortran: F2008 passing of internal procs to a proc pointer [PR117434]

2024-11-05 Thread Paul Thomas via Gcc-cvs
https://gcc.gnu.org/g:4dbf4c0fdb188e1c348688de91e010f696cd59fc

commit r15-4974-g4dbf4c0fdb188e1c348688de91e010f696cd59fc
Author: Paul Thomas 
Date:   Wed Nov 6 07:17:25 2024 +

Fortran: F2008 passing of internal procs to a proc pointer [PR117434]

2024-11-06  Paul Thomas  

gcc/fortran
PR fortran/117434
* interface.cc (gfc_compare_actual_formal): Skip 'Expected a
procedure pointer error' if the formal argument typespec has an
interface and the type of the actual arg is BT_PROCEDURE.

gcc/testsuite/
PR fortran/117434
* gfortran.dg/proc_ptr_54.f90: New test. This is temporarily
compile-only until one one seven four five five is fixed.
* gfortran.dg/proc_ptr_55.f90: New test.
* gfortran.dg/proc_ptr_56.f90: New test.

Diff:
---
 gcc/fortran/interface.cc  |  9 ++-
 gcc/testsuite/gfortran.dg/proc_ptr_54.f90 | 95 +++
 gcc/testsuite/gfortran.dg/proc_ptr_55.f90 | 87 
 gcc/testsuite/gfortran.dg/proc_ptr_56.f90 | 45 +++
 4 files changed, 234 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index 69519fe3168e..61c506bfdb5d 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -3513,12 +3513,17 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, 
gfc_formal_arglist *formal,
 
  skip_size_check:
 
-  /* Satisfy F03:12.4.1.3 by ensuring that a procedure pointer actual
- argument is provided for a procedure pointer formal argument.  */
+  /* Satisfy either: F03:12.4.1.3 by ensuring that a procedure pointer
+actual argument is provided for a procedure pointer formal argument;
+or: F08:12.5.2.9 (F18:15.5.2.10) by ensuring that the effective
+argument shall be an external, internal, module, or dummy procedure.
+The interfaces are checked elsewhere.  */
   if (f->sym->attr.proc_pointer
  && !((a->expr->expr_type == EXPR_VARIABLE
&& (a->expr->symtree->n.sym->attr.proc_pointer
|| gfc_is_proc_ptr_comp (a->expr)))
+  || (a->expr->ts.type == BT_PROCEDURE
+  && f->sym->ts.interface)
   || (a->expr->expr_type == EXPR_FUNCTION
   && is_procptr_result (a->expr
{
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_54.f90 
b/gcc/testsuite/gfortran.dg/proc_ptr_54.f90
new file mode 100644
index ..e03ecb507400
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_54.f90
@@ -0,0 +1,95 @@
+! { dg-do compile }
+!
+! Test the fix for pr117434, in which the F2008 addition of being permitted to
+! pass an external, internal or module procedure to a dummy procedure pointer
+! gave the error "Expected a procedure pointer for argument ‘’ at 
(1).
+!
+! This testcase checks for correct results.
+!
+! Contributed by Damian Rouson  
+!
+module julienne_test_description_m
+  implicit none
+
+  abstract interface
+logical function test_function_i(arg)
+  integer, intent(in) :: arg
+end function
+  end interface
+
+  type test_description_t
+procedure(test_function_i), pointer, nopass :: test_function_
+  end type
+
+
+contains
+
+  type(test_description_t) function new_test_description(test_function)
+procedure(test_function_i), intent(in), pointer :: test_function
+new_test_description%test_function_ => test_function
+  end function
+
+end module
+
+module test_mod
+
+contains
+
+  logical function mod_test(arg)
+integer, intent(in) :: arg
+if (arg == 1) then
+  mod_test = .true.
+else
+  mod_test = .false.
+endif
+  end function
+
+end
+
+logical function ext_test(arg)
+  integer, intent(in) :: arg
+  if (arg == 2) then
+ext_test = .true.
+  else
+ext_test = .false.
+  endif
+end function
+
+  use julienne_test_description_m
+  use test_mod
+  implicit none
+  type(test_description_t) test_description
+
+  interface
+logical function ext_test(arg)
+  integer, intent(in) :: arg
+end function
+  end interface
+
+  test_description = new_test_description(test)
+  if (test_description%test_function_(1) &
+  .or. test_description%test_function_(2) &
+  .or. .not.test_description%test_function_(3)) stop 1
+
+  test_description = new_test_description(mod_test)
+  if (test_description%test_function_(2) &
+  .or. test_description%test_function_(3) &
+  .or. .not.test_description%test_function_(1)) stop 2
+
+  test_description = new_test_description(ext_test)
+  if (test_description%test_function_(1) &
+  .or. test_description%test_function_(3) &
+  .or. .not.test_description%test_function_(2)) stop 3
+
+contains
+
+  logical function test(arg)
+integer, intent(in) :: arg
+if (arg == 3) then
+  test = .true.
+else
+  test = .false.
+endif
+  end function
+
+end
diff --git a/gcc/testsuit