commit 306cdb4df729079d7bd924e0023693181163e2e3
Author: Richard Biener
Date: Fri May 23 13:15:18 2025
Bump BASE-VER.
* BASE-VER: Set to 14.3.1.
diff --git a/gcc/BASE-VER b/gcc/BASE-VER
index 32f02f10ebe..6dfe8b1298c 100644
--- a/gcc/BASE-VER
+++ b/gcc/BASE-VER
@@ -1 +1 @@
-14.3.0
+14.3.1
commit 98d5b27b53f0a227ce2f30d21fb96989a2b8aa5c
Author: GCC Administrator
Date: Sat May 24 02:22:28 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 809477a289d..cc6fc26c514 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250523
+20250524
commit a6f18c2a9d50edc263539ba0a64653a8a00d6d89
Author: GCC Administrator
Date: Sun May 25 02:22:15 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index cc6fc26c514..87d53b31150 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250524
+20250525
commit f644e21ee364405213a8609bbd8371c27fdb69d9
Author: Michael J. Eager
Date: Sat May 24 23:54:55 2025
MicroBlaze does not support speculative execution (CVE-2017-5753)
gcc/
PR target/86772
Tracking CVE-2017-5753
* config/microblaze/microblaze.cc (TARGET_HAVE_SPECULATION_SAFE_VALUE):
Define to speculation_save_value_not_needed
diff --git a/gcc/config/microblaze/microblaze.cc b/gcc/config/microblaze/microblaze.cc
index 98ec6116ffd..26eb007b844 100644
--- a/gcc/config/microblaze/microblaze.cc
+++ b/gcc/config/microblaze/microblaze.cc
@@ -239,6 +239,10 @@ section *sdata2_section;
#define TARGET_HAVE_TLS true
#endif
+/* MicroBlaze does not do speculative execution. */
+#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
+#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
+
/* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
static bool
microblaze_const_double_ok (rtx op, machine_mode mode)
commit 9c21d7eaf8383749d1a9cd266709ec9ed04e3a00
Author: Harald Anlauf
Date: Thu Aug 29 22:17:07 2024
Fortran: default-initialization of derived-type function results [PR98454]
gcc/fortran/ChangeLog:
PR fortran/98454
* resolve.cc (resolve_symbol): Add default-initialization of
non-allocatable, non-pointer derived-type function results.
gcc/testsuite/ChangeLog:
PR fortran/98454
* gfortran.dg/alloc_comp_class_4.f03: Remove bogus pattern.
* gfortran.dg/pdt_26.f03: Adjust expected count.
* gfortran.dg/derived_result_3.f90: New test.
(cherry picked from commit b222122d4e93de2238041a01b1886c7dfd9944da)
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 4f4decd1bc3..4d8484a36f1 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -17140,6 +17140,9 @@ skip_interfaces:
/* Mark the result symbol to be referenced, when it has allocatable
components. */
sym->result->attr.referenced = 1;
+ else if (a->function && !a->pointer && !a->allocatable && sym->result)
+ /* Default initialization for function results. */
+ apply_default_init (sym->result);
}
if (sym->ts.type == BT_CLASS && sym->ns == gfc_current_ns
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
index 3118b552a30..4a55d73b245 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
@@ -71,7 +71,7 @@ contains
allocatable :: t_init
end function
- type(t) function static_t_init() ! { dg-warning "not set" }
+ type(t) function static_t_init()
end function
end module test_pr58586_mod
diff --git a/gcc/testsuite/gfortran.dg/derived_result_3.f90 b/gcc/testsuite/gfortran.dg/derived_result_3.f90
new file mode 100644
index 00000000000..4b28f7e28c9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/derived_result_3.f90
@@ -0,0 +1,158 @@
+! { dg-do run }
+! PR fortran/98454 - default-initialization of derived-type function results
+
+program test
+ implicit none
+ type t
+ integer :: unit = -1
+ end type t
+ type u
+ integer, allocatable :: unit(:)
+ end type u
+ type(t) :: x, x3(3)
+ type(u) :: y, y4(4)
+
+ ! Scalar function result, DT with default initializer
+ x = t(42)
+ if (x% unit /= 42) stop 1
+ x = g()
+ if (x% unit /= -1) stop 2
+ x = t(42)
+ x = f()
+ if (x% unit /= -1) stop 3
+ x = t(42)
+ x = h()
+ if (x% unit /= -1) stop 4
+ x = t(42)
+ x = k()
+ if (x% unit /= -1) stop 5
+
+ ! Array function result, DT with default initializer
+ x3 = t(13)
+ if (any (x3% unit /= 13)) stop 11
+ x3 = f3()
+ if (any (x3% unit /= -1)) stop 12
+ x3 = t(13)
+ x3 = g3()
+ if (any (x3% unit /= -1)) stop 13
+ x3 = t(13)
+ x3 = h3()
+ if (any (x3% unit /= -1)) stop 14
+ x3 = t(13)
+ x3 = k3()
+ if (any (x3% unit /= -1)) stop 15
+
+ ! Scalar function result, DT with allocatable component
+ y = u()
+ if (allocated (y% unit)) stop 21
+ allocate (y% unit(42))
+ y = m()
+ if (allocated (y% unit)) stop 22
+ allocate (y% unit(42))
+ y = n()
+ if (allocated (y% unit)) stop 23
+ allocate (y% unit(42))
+ y = o()
+ if (allocated (y% unit)) stop 24
+ allocate (y% unit(42))
+ y = p()
+ if (allocated (y% unit)) stop 25
+
+ ! Array function result, DT with allocatable component
+ y4 = u()
+ if (allocated (y4(1)% unit)) stop 31
+ allocate (y4(1)% unit(42))
+ y4 = m4()
+ if (allocated (y4(1)% unit)) stop 32
+ y4 = u()
+ allocate (y4(1)% unit(42))
+ y4 = n4()
+ if (allocated (y4(1)% unit)) stop 33
+
+ y4 = u()
+ allocate (y4(1)% unit(42))
+ y4 = o4()
+ if (allocated (y4(1)% unit)) stop 34
+ y4 = u()
+ allocate (y4(1)% unit(42))
+ y4 = p4()
+ if (allocated (y4(1)% unit)) stop 35
+
+contains
+
+ ! Function result not referenced within function body
+ function f()
+ type(t) :: f
+ end function f
+
+ function k() result (f)
+ type(t) :: f
+ end function k
+
+ ! Function result referenced within function body
+ function g()
+ type(t) :: g
+ if (g% unit /= -1) stop 41
+ end function g
+
+ function h() result (g)
+ type(t) :: g
+ if (g% unit /= -1) stop 42
+ end function h
+
+ ! Function result not referenced within function body
+ function f3 ()
+ type(t) :: f3(3)
+ end function f3
+
+ function k3() result (f3)
+ type(t) :: f3(3)
+ end function k3
+
+ ! Function result referenced within function body
+ function g3()
+ type(t) :: g3(3)
+ if (any (g3% unit /= -1)) stop 43
+ end function g3
+
+ function h3() result (g3)
+ type(t) :: g3(3)
+ if (any (g3% unit /= -1)) stop 44
+ end function h3
+
+ function m()
+ type(u) :: m
+ end function m
+
+ function n() result (f)
+ type(u) :: f
+ end function n
+
+ function o()
+ type(u) :: o
+ if (allocated (o% unit)) stop 71
+ end function o
+
+ function p() result (f)
+ type(u) :: f
+ if (allocated (f% unit)) stop 72
+ end function p
+
+ function m4()
+ type(u) :: m4(4)
+ end function m4
+
+ function n4() result (f)
+ type(u) :: f(4)
+ end function n4
+
+ function o4()
+ type(u) :: o4(4)
+ if (allocated (o4(1)% unit)) stop 73
+ end function o4
+
+ function p4() result (f)
+ type(u) :: f(4)
+ if (allocated (f(1)% unit)) stop 74
+ end function p4
+end
diff --git a/gcc/testsuite/gfortran.dg/pdt_26.f03 b/gcc/testsuite/gfortran.dg/pdt_26.f03
index 59ddcfb6cc4..b7e3bb600b4 100644
--- a/gcc/testsuite/gfortran.dg/pdt_26.f03
+++ b/gcc/testsuite/gfortran.dg/pdt_26.f03
@@ -43,4 +43,4 @@ program test_pdt
if (any (c(1)%foo .ne. [13,15,17])) STOP 2
end program test_pdt
! { dg-final { scan-tree-dump-times "__builtin_free" 8 "original" } }
-! { dg-final { scan-tree-dump-times "__builtin_malloc" 8 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_malloc" 9 "original" } }
commit 0100ea2b4eb1c83972e0db07503a7cfe8a38932e
Author: Harald Anlauf
Date: Thu May 15 21:07:07 2025
Fortran: default-initialization and functions returning derived type [PR85750]
Functions with non-pointer, non-allocatable result and of derived type did
not always get initialized although the type had default-initialization,
and a derived type component had the allocatable or pointer attribute.
Rearrange the logic when to apply default-initialization.
PR fortran/85750
gcc/fortran/ChangeLog:
* resolve.cc (resolve_symbol): Reorder conditions when to apply
default-initializers.
gcc/testsuite/ChangeLog:
* gfortran.dg/alloc_comp_auto_array_3.f90: Adjust scan counts.
* gfortran.dg/alloc_comp_class_3.f03: Remove bogus warnings.
* gfortran.dg/alloc_comp_class_4.f03: Likewise.
* gfortran.dg/allocate_with_source_14.f03: Adjust scan count.
* gfortran.dg/derived_constructor_comps_6.f90: Likewise.
* gfortran.dg/derived_result_5.f90: New test.
(cherry picked from commit d31ab498b12ebbe4f50acb2aa240ff92c73f310c)
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 4d8484a36f1..10a9e58b287 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -17134,15 +17134,16 @@ skip_interfaces:
|| (a->dummy && !a->pointer && a->intent == INTENT_OUT
&& sym->ns->proc_name->attr.if_source != IFSRC_IFBODY))
apply_default_init (sym);
+ else if (a->function && !a->pointer && !a->allocatable && !a->use_assoc
+ && sym->result)
+ /* Default initialization for function results. */
+ apply_default_init (sym->result);
else if (a->function && sym->result && a->access != ACCESS_PRIVATE
&& (sym->ts.u.derived->attr.alloc_comp
|| sym->ts.u.derived->attr.pointer_comp))
/* Mark the result symbol to be referenced, when it has allocatable
components. */
sym->result->attr.referenced = 1;
- else if (a->function && !a->pointer && !a->allocatable && sym->result)
- /* Default initialization for function results. */
- apply_default_init (sym->result);
}
if (sym->ts.type == BT_CLASS && sym->ns == gfc_current_ns
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_3.f90 b/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_3.f90
index 2af089e84e8..d0751f3d3eb 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_3.f90
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_3.f90
@@ -25,6 +25,6 @@ contains
allocate (array(1)%bigarr)
end function
end
-! { dg-final { scan-tree-dump-times "builtin_malloc" 3 "original" } }
+! { dg-final { scan-tree-dump-times "builtin_malloc" 4 "original" } }
! { dg-final { scan-tree-dump-times "builtin_free" 3 "original" } }
-! { dg-final { scan-tree-dump-times "while \\(1\\)" 4 "original" } }
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 5 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03 b/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03
index 0753e33d535..8202d783621 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03
@@ -45,11 +45,10 @@ contains
type(c), value :: d
end subroutine
- type(c) function c_init() ! { dg-warning "not set" }
+ type(c) function c_init()
end function
subroutine sub(d)
type(u), value :: d
end subroutine
end program test_pr58586
-
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
index 4a55d73b245..9ff38e3fb7c 100644
--- a/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03
@@ -51,14 +51,14 @@ contains
type(t), value :: d
end subroutine
- type(c) function c_init() ! { dg-warning "not set" }
+ type(c) function c_init()
end function
class(c) function c_init2() ! { dg-warning "not set" }
allocatable :: c_init2
end function
- type(c) function d_init(this) ! { dg-warning "not set" }
+ type(c) function d_init(this)
class(d) :: this
end function
@@ -102,4 +102,3 @@ program test_pr58586
call add_c(oe%init())
deallocate(oe)
end program
-
diff --git a/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03 b/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03
index fd2db7439fe..36c1245ccdd 100644
--- a/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03
+++ b/gcc/testsuite/gfortran.dg/allocate_with_source_14.f03
@@ -210,5 +210,5 @@ program main
call v%free()
deallocate(av)
end program
-! { dg-final { scan-tree-dump-times "__builtin_malloc" 22 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_malloc" 23 "original" } }
! { dg-final { scan-tree-dump-times "__builtin_free" 29 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90 b/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90
index bdfa47b1df5..406e031456f 100644
--- a/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90
+++ b/gcc/testsuite/gfortran.dg/derived_constructor_comps_6.f90
@@ -129,5 +129,5 @@ contains
prt_spec = name
end function new_prt_spec3
end program main
-! { dg-final { scan-tree-dump-times "__builtin_malloc" 15 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_malloc" 16 "original" } }
! { dg-final { scan-tree-dump-times "__builtin_free" 33 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/derived_result_5.f90 b/gcc/testsuite/gfortran.dg/derived_result_5.f90
new file mode 100644
index 00000000000..1ba4d19dc44
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/derived_result_5.f90
@@ -0,0 +1,123 @@
+! { dg-do run }
+! { dg-additional-options "-O2 -Wreturn-type" }
+!
+! PR fortran/85750 - default-initialization and functions returning derived type
+
+module bar
+ implicit none
+ type ilist
+ integer :: count = 42
+ integer, pointer :: ptr(:) => null()
+ end type ilist
+
+ type jlist
+ real, allocatable :: a(:)
+ integer :: count = 23
+ end type jlist
+
+contains
+
+ function make_list(i)
+ integer, intent(in) :: i
+ type(ilist), dimension(2) :: make_list
+ make_list(i)%count = i
+ end function make_list
+
+ function make_list_res(i) result(list)
+ integer, intent(in) :: i
+ type(ilist), dimension(2) :: list
+ list(i)%count = i
+ end function make_list_res
+
+ function make_jlist(i)
+ integer, intent(in) :: i
+ type(jlist), dimension(2) :: make_jlist
+ make_jlist(i)%count = i
+ end function make_jlist
+
+ function make_jlist_res(i) result(list)
+ integer, intent(in) :: i
+ type(jlist), dimension(2) :: list
+ list(i)%count = i
+ end function make_jlist_res
+
+ function empty_ilist()
+ type(ilist), dimension(2) :: empty_ilist
+ end function
+
+ function empty_jlist()
+ type(jlist), dimension(2) :: empty_jlist
+ end function
+
+ function empty_ilist_res() result (res)
+ type(ilist), dimension(2) :: res
+ end function
+
+ function empty_jlist_res() result (res)
+ type(jlist), dimension(2) :: res
+ end function
+
+end module bar
+
+program foo
+ use bar
+ implicit none
+ type(ilist) :: mylist(2) = ilist(count=-2)
+ type(jlist), allocatable :: yourlist(:)
+
+ mylist = ilist(count=-1)
+ if (any (mylist%count /= [-1,-1])) stop 1
+ mylist = empty_ilist()
+ if (any (mylist%count /= [42,42])) stop 2
+ mylist = ilist(count=-1)
+ mylist = empty_ilist_res()
+ if (any (mylist%count /= [42,42])) stop 3
+
+ allocate(yourlist(1:2))
+ if (any (yourlist%count /= [23,23])) stop 4
+ yourlist = jlist(count=-1)
+ if (any (yourlist%count /= [-1,-1])) stop 5
+ yourlist = empty_jlist()
+ if (any (yourlist%count /= [23,23])) stop 6
+ yourlist = jlist(count=-1)
+ yourlist = empty_jlist_res()
+ if (any (yourlist%count /= [23,23])) stop 7
+
+ mylist = make_list(1)
+ if (any (mylist%count /= [1,42])) stop 11
+ mylist = make_list(2)
+ if (any (mylist%count /= [42,2])) stop 12
+ mylist = (make_list(1))
+ if (any (mylist%count /= [1,42])) stop 13
+ mylist = [make_list(2)]
+ if (any (mylist%count /= [42,2])) stop 14
+
+ mylist = make_list_res(1)
+ if (any (mylist%count /= [1,42])) stop 21
+ mylist = make_list_res(2)
+ if (any (mylist%count /= [42,2])) stop 22
+ mylist = (make_list_res(1))
+ if (any (mylist%count /= [1,42])) stop 23
+ mylist = [make_list_res(2)]
+ if (any (mylist%count /= [42,2])) stop 24
+
+ yourlist = make_jlist(1)
+ if (any (yourlist%count /= [1,23])) stop 31
+ yourlist = make_jlist(2)
+ if (any (yourlist%count /= [23,2])) stop 32
+ yourlist = (make_jlist(1))
+ if (any (yourlist%count /= [1,23])) stop 33
+ yourlist = [make_jlist(2)]
+ if (any (yourlist%count /= [23,2])) stop 34
+
+ yourlist = make_jlist_res(1)
+ if (any (yourlist%count /= [1,23])) stop 41
+ yourlist = make_jlist_res(2)
+ if (any (yourlist%count /= [23,2])) stop 42
+ yourlist = (make_jlist_res(1))
+ if (any (yourlist%count /= [1,23])) stop 43
+ yourlist = [make_jlist_res(2)]
+ if (any (yourlist%count /= [23,2])) stop 44
+
+ deallocate (yourlist)
+end program foo
commit 7d5979a65577cfb80d18e101e8b8bd1b1240ae4b
Author: GCC Administrator
Date: Mon May 26 02:21:16 2025
Daily bump.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 314b0a65fd2..541b6babe73 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2025-05-25 Michael J. Eager
+
+ PR target/86772
+ Tracking CVE-2017-5753
+ * config/microblaze/microblaze.cc (TARGET_HAVE_SPECULATION_SAFE_VALUE):
+ Define to speculation_save_value_not_needed
+
2025-05-23 Release Manager
* GCC 14.3.0 released.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 87d53b31150..dbf258be4a2 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250525
+20250526
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 4ccbea18878..12ead9dfc79 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,21 @@
+2025-05-25 Harald Anlauf
+
+ Backported from master:
+ 2025-05-15 Harald Anlauf
+
+ PR fortran/85750
+ * resolve.cc (resolve_symbol): Reorder conditions when to apply
+ default-initializers.
+
+2025-05-25 Harald Anlauf
+
+ Backported from master:
+ 2024-08-30 Harald Anlauf
+
+ PR fortran/98454
+ * resolve.cc (resolve_symbol): Add default-initialization of
+ non-allocatable, non-pointer derived-type function results.
+
2025-05-23 Release Manager
* GCC 14.3.0 released.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 64d04634e7c..23d940b9d1b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,26 @@
+2025-05-25 Harald Anlauf
+
+ Backported from master:
+ 2025-05-15 Harald Anlauf
+
+ PR fortran/85750
+ * gfortran.dg/alloc_comp_auto_array_3.f90: Adjust scan counts.
+ * gfortran.dg/alloc_comp_class_3.f03: Remove bogus warnings.
+ * gfortran.dg/alloc_comp_class_4.f03: Likewise.
+ * gfortran.dg/allocate_with_source_14.f03: Adjust scan count.
+ * gfortran.dg/derived_constructor_comps_6.f90: Likewise.
+ * gfortran.dg/derived_result_5.f90: New test.
+
+2025-05-25 Harald Anlauf
+
+ Backported from master:
+ 2024-08-30 Harald Anlauf
+
+ PR fortran/98454
+ * gfortran.dg/alloc_comp_class_4.f03: Remove bogus pattern.
+ * gfortran.dg/pdt_26.f03: Adjust expected count.
+ * gfortran.dg/derived_result_3.f90: New test.
+
2025-05-23 Release Manager
* GCC 14.3.0 released.
commit e326152845584d78410963e5c3d31cdbdf8f50fe
Author: Jakub Jelinek
Date: Thu Nov 28 10:51:16 2024
gimple-fold: Avoid ICEs with bogus declarations like const attribute no snprintf [PR117358]
When one puts incorrect const or pure attributes on declarations of various
C APIs which have corresponding builtins (vs. what they actually do), we can
get tons of ICEs in gimple-fold.cc.
The following patch fixes it by giving up gimple_fold_builtin_* folding
if the functions don't have gimple_vdef (or for pure functions like
bcmp/strchr/strstr gimple_vuse) when in SSA form (during gimplification
they will surely have both of those NULL even when declared correctly,
yet it is highly desirable to fold them).
Or shall I replace
!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)
tests with
(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE | ECF_NOVOPS)) != 0
and
!gimple_vuse (stmt) && gimple_in_ssa_p (cfun)
with
(gimple_call_flags (stmt) & (ECF_CONST | ECF_NOVOPS)) != 0
?
2024-11-28 Jakub Jelinek
PR tree-optimization/117358
* gimple-fold.cc (gimple_fold_builtin_memory_op): Punt if stmt has no
vdef in ssa form.
(gimple_fold_builtin_bcmp): Punt if stmt has no vuse in ssa form.
(gimple_fold_builtin_bcopy): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_bzero): Likewise.
(gimple_fold_builtin_memset): Likewise. Use return false instead of
return NULL_TREE.
(gimple_fold_builtin_strcpy): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_strncpy): Likewise.
(gimple_fold_builtin_strchr): Punt if stmt has no vuse in ssa form.
(gimple_fold_builtin_strstr): Likewise.
(gimple_fold_builtin_strcat): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_strcat_chk): Likewise.
(gimple_fold_builtin_strncat): Likewise.
(gimple_fold_builtin_strncat_chk): Likewise.
(gimple_fold_builtin_string_compare): Likewise.
(gimple_fold_builtin_fputs): Likewise.
(gimple_fold_builtin_memory_chk): Likewise.
(gimple_fold_builtin_stxcpy_chk): Likewise.
(gimple_fold_builtin_stxncpy_chk): Likewise.
(gimple_fold_builtin_stpcpy): Likewise.
(gimple_fold_builtin_snprintf_chk): Likewise.
(gimple_fold_builtin_sprintf_chk): Likewise.
(gimple_fold_builtin_sprintf): Likewise.
(gimple_fold_builtin_snprintf): Likewise.
(gimple_fold_builtin_fprintf): Likewise.
(gimple_fold_builtin_printf): Likewise.
(gimple_fold_builtin_realloc): Likewise.
* gcc.c-torture/compile/pr117358.c: New test.
(cherry picked from commit 29032dfa57629d1713a97b17a785273823993a91)
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 3548c914482..0d90bab595f 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -936,6 +936,8 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
}
goto done;
}
+ else if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
else
{
/* We cannot (easily) change the type of the copy if it is a storage
@@ -1377,6 +1379,8 @@ gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
/* Transform bcmp (a, b, len) into memcmp (a, b, len). */
gimple *stmt = gsi_stmt (*gsi);
+ if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
+ return false;
tree a = gimple_call_arg (stmt, 0);
tree b = gimple_call_arg (stmt, 1);
tree len = gimple_call_arg (stmt, 2);
@@ -1403,6 +1407,8 @@ gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
len) into memmove (dest, src, len). */
gimple *stmt = gsi_stmt (*gsi);
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
tree src = gimple_call_arg (stmt, 0);
tree dest = gimple_call_arg (stmt, 1);
tree len = gimple_call_arg (stmt, 2);
@@ -1428,6 +1434,8 @@ gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
/* Transform bzero (dest, len) into memset (dest, 0, len). */
gimple *stmt = gsi_stmt (*gsi);
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
tree dest = gimple_call_arg (stmt, 0);
tree len = gimple_call_arg (stmt, 1);
@@ -1457,6 +1465,9 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
return true;
}
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
if (! tree_fits_uhwi_p (len))
return false;
@@ -1479,20 +1490,20 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
if ((!INTEGRAL_TYPE_P (etype)
&& !POINTER_TYPE_P (etype))
|| TREE_CODE (etype) == BITINT_TYPE)
- return NULL_TREE;
+ return false;
if (! var_decl_component_p (var))
- return NULL_TREE;
+ return false;
length = tree_to_uhwi (len);
if (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (etype)) != length
|| (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (etype))
!= GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (etype)))
|| get_pointer_alignment (dest) / BITS_PER_UNIT < length)
- return NULL_TREE;
+ return false;
if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
- return NULL_TREE;
+ return false;
if (!type_has_mode_precision_p (etype))
etype = lang_hooks.types.type_for_mode (SCALAR_INT_TYPE_MODE (etype),
@@ -2106,7 +2117,7 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
return false;
}
- if (!len)
+ if (!len || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
len = fold_convert_loc (loc, size_type_node, len);
@@ -2181,7 +2192,7 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
/* OK transform into builtin memcpy. */
tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
- if (!fn)
+ if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
len = fold_convert_loc (loc, size_type_node, len);
@@ -2235,7 +2246,7 @@ gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi, bool is_strrchr)
return true;
}
- if (!integer_zerop (c))
+ if (!integer_zerop (c) || (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun)))
return false;
/* Transform strrchr (s, 0) to strchr (s, 0) when optimizing for size. */
@@ -2333,6 +2344,9 @@ gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
return true;
}
+ if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
/* Transform strstr (x, "c") into strchr (x, 'c'). */
if (q[1] == '\0')
{
@@ -2385,6 +2399,9 @@ gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
if (!optimize_bb_for_speed_p (gimple_bb (stmt)))
return false;
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
/* See if we can store by pieces into (dst + strlen(dst)). */
tree newdst;
tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
@@ -2454,7 +2471,6 @@ gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
tree fn;
const char *p;
-
p = c_getstr (src);
/* If the SRC parameter is "", return DEST. */
if (p && *p == '\0')
@@ -2466,6 +2482,9 @@ gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
if (! tree_fits_uhwi_p (size) || ! integer_all_onesp (size))
return false;
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
/* If __builtin_strcat_chk is used, assume strcat is available. */
fn = builtin_decl_explicit (BUILT_IN_STRCAT);
if (!fn)
@@ -2556,7 +2575,7 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
/* If the replacement _DECL isn't initialized, don't do the
transformation. */
- if (!fn)
+ if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
/* Otherwise, emit a call to strcat. */
@@ -2588,6 +2607,9 @@ gimple_fold_builtin_strncat_chk (gimple_stmt_iterator *gsi)
return true;
}
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
if (! integer_all_onesp (size))
{
tree src_len = c_strlen (src, 1);
@@ -2678,6 +2700,9 @@ gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
return true;
}
+ if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
/* Initially set to the number of characters, including the terminating
nul if each array has one. LENx == strnlen (Sx, LENx) implies that
the array Sx is not terminated by a nul.
@@ -2970,7 +2995,7 @@ gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
const char *p = c_getstr (arg0);
if (p != NULL)
{
- if (!fn_fputc)
+ if (!fn_fputc || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
gimple *repl
@@ -2989,7 +3014,7 @@ gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
return false;
/* New argument list transforming fputs(string, stream) to
fwrite(string, 1, len, stream). */
- if (!fn_fwrite)
+ if (!fn_fwrite || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
gimple *repl
@@ -3040,6 +3065,9 @@ gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
}
}
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
if (! integer_all_onesp (size)
&& !known_lower (stmt, len, size)
@@ -3138,6 +3166,9 @@ gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
return true;
}
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
tree maxlen = get_maxval_strlen (src, SRK_STRLENMAX);
if (! integer_all_onesp (size))
{
@@ -3231,7 +3262,7 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
/* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available. */
fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK && !ignore
? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
- if (!fn)
+ if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
gcall *repl = gimple_build_call (fn, 3, dest, src, len);
@@ -3252,6 +3283,9 @@ gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
tree src = gimple_call_arg (stmt, 1);
tree fn, lenp1;
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
/* If the result is unused, replace stpcpy with strcpy. */
if (gimple_call_lhs (stmt) == NULL_TREE)
{
@@ -3369,7 +3403,7 @@ gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
available. */
fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
- if (!fn)
+ if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
/* Replace the called function and the first 5 argument by 3 retaining
@@ -3456,7 +3490,7 @@ gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi,
/* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
- if (!fn)
+ if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
/* Replace the called function and the first 4 argument by 2 retaining
@@ -3505,7 +3539,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
return false;
tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
- if (!fn)
+ if (!fn || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
/* If the format doesn't contain % args or %%, use strcpy. */
@@ -3618,7 +3652,8 @@ gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
tree orig = NULL_TREE;
const char *fmt_str = NULL;
- if (gimple_call_num_args (stmt) > 4)
+ if (gimple_call_num_args (stmt) > 4
+ || (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)))
return false;
if (gimple_call_num_args (stmt) == 4)
@@ -3776,6 +3811,9 @@ gimple_fold_builtin_fprintf (gimple_stmt_iterator *gsi,
if (!init_target_chars ())
return false;
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
/* If the format doesn't contain % args or %%, use strcpy. */
if (strchr (fmt_str, target_percent) == NULL)
{
@@ -3855,6 +3893,9 @@ gimple_fold_builtin_printf (gimple_stmt_iterator *gsi, tree fmt,
if (gimple_call_lhs (stmt) != NULL_TREE)
return false;
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
/* Check whether the format is a literal string constant. */
fmt_str = c_getstr (fmt);
if (fmt_str == NULL)
@@ -4096,6 +4137,9 @@ gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
tree arg = gimple_call_arg (stmt, 0);
tree size = gimple_call_arg (stmt, 1);
+ if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+ return false;
+
if (operand_equal_p (arg, null_pointer_node, 0))
{
tree fn_malloc = builtin_decl_implicit (BUILT_IN_MALLOC);
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr117358.c b/gcc/testsuite/gcc.c-torture/compile/pr117358.c
new file mode 100644
index 00000000000..023284aff96
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr117358.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/117358 */
+
+char a;
+/* This attribute is bogus, snprintf isn't const. Just verify we don't ICE on it. */
+int __attribute__((const)) snprintf (char *, __SIZE_TYPE__, const char *, ...);
+
+long
+foo (long d)
+{
+ return snprintf (&a, d, "");
+}
+
+int
+bar (void)
+{
+ return foo (1);
+}
commit cfd7c674139097d12546d034f7869e272457aa56
Author: Jakub Jelinek
Date: Wed Feb 5 13:16:17 2025
cselib: For CALL_INSNs to const/pure fns invalidate memory below sp [PR117239]
The following testcase is miscompiled on x86_64 during postreload.
After reload (with IPA-RA figuring out the calls don't modify any
registers but %rax for return value) postreload sees
(insn 14 12 15 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp)
(const_int 16 [0x10])) [0 S8 A64])
(reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":18:7 95 {*movdi_internal}
(nil))
(call_insn/i 15 14 16 2 (set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI ("baz") [flags 0x3] ) [0 baz S1 A8])
(const_int 24 [0x18]))) "pr117239.c":18:7 1476 {*call_value}
(expr_list:REG_CALL_DECL (symbol_ref:DI ("baz") [flags 0x3] )
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 16 15 18 2 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 24 [0x18])))
(clobber (reg:CC 17 flags))
]) "pr117239.c":18:7 285 {*adddi_1}
(expr_list:REG_ARGS_SIZE (const_int 0 [0])
(nil)))
...
(call_insn/i 19 18 21 2 (set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI ("foo") [flags 0x3] ) [0 foo S1 A8])
(const_int 0 [0]))) "pr117239.c":19:3 1476 {*call_value}
(expr_list:REG_CALL_DECL (symbol_ref:DI ("foo") [flags 0x3] )
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 21 19 26 2 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int -24 [0xffffffffffffffe8])))
(clobber (reg:CC 17 flags))
]) "pr117239.c":19:3 discrim 1 285 {*adddi_1}
(expr_list:REG_ARGS_SIZE (const_int 24 [0x18])
(nil)))
(insn 26 21 24 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp)
(const_int 16 [0x10])) [0 S8 A64])
(reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":19:3 discrim 1 95 {*movdi_internal}
(nil))
i.e.
movq %rdx, 16(%rsp)
call baz
addq $24, %rsp
...
call foo
subq $24, %rsp
movq %rdx, 16(%rsp)
Now, postreload uses cselib and cselib remembered that %rdx value has been
stored into 16(%rsp). Both baz and foo are pure calls. If they weren't,
when processing those CALL_INSNs cselib would invalidate all MEMs
if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
|| !(RTL_CONST_OR_PURE_CALL_P (insn)))
cselib_invalidate_mem (callmem);
where callmem is (mem:BLK (scratch)). But they are pure, so instead the
code just invalidates the argument slots from CALL_INSN_FUNCTION_USAGE.
The calls actually clobber more than that, even const/pure calls clobber
all memory below the stack pointer. And that is something that hasn't been
invalidated. In this failing testcase, the call to baz is not a big deal,
we don't have anything remembered in memory below %rsp at that call.
But then we increment %rsp by 24, so the %rsp+16 is now 8 bytes below stack
and do the call to foo. And that call now actually, not just in theory,
clobbers the memory below the stack pointer (in particular overwrites it
with the return value). But cselib does not invalidate. Then %rsp
is decremented again (in preparation for another call, to bar) and cselib
is processing store of %rdx (which IPA-RA says has not been modified by
either baz or foo calls) to %rsp + 16, and it sees the memory already has
that value, so the store is useless, let's remove it.
But it is not, the call to foo has changed it, so it needs to be stored
again.
The following patch adds targetted invalidation of memory below stack
pointer (or on SPARC memory below stack pointer + 2047 when stack bias is
used, or on PA memory above stack pointer instead).
It does so only in !ACCUMULATE_OUTGOING_ARGS or cfun->calls_alloca functions,
because in other functions the stack pointer should be constant from
the end of prologue till start of epilogue and so nothing should be stored
within the function below the stack pointer.
Now, memory below stack pointer is special, except for functions using
alloca/VLAs I believe no addressable memory should be there, it should be
purely outgoing function argument area, if we take address of some automatic
variable, it should live all the time above the outgoing function argument
area. So on top of just trying to flush memory below stack pointer
(represented by %rsp - PTRDIFF_MAX with PTRDIFF_MAX size on most arches),
the patch tries to optimize and only invalidate memory that has address
clearly derived from stack pointer (memory with other bases is not
invalidated) and if we can prove (we see same SP_DERIVED_VALUE_P bases in
both VALUEs) it is above current stack, also don't call
canon_anti_dependence which might just give up in certain cases.
I've gathered statistics from x86_64-linux and i686-linux
bootstraps/regtests. During -m64 compilations from those, there were
3718396 + 42634 + 27761 cases of processing MEMs in cselib_invalidate_mem
(callmem[1]) calls, the first number is number of MEMs not invalidated
because of the optimization, i.e.
+ if (sp_derived_base == NULL_RTX)
+ {
+ has_mem = true;
+ num_mems++;
+ p = &(*p)->next;
+ continue;
+ }
in the patch, the second number is number of MEMs not invalidated because
canon_anti_dependence returned false and finally the last number is number
of MEMs actually invalidated (so that is what hasn't been invalidated
before). During -m32 compilations the numbers were
1422412 + 39354 + 16509 with the same meaning.
Note, when there is no red zone, in theory even the sp = sp + incr
instruction invalidates memory below the new stack pointer, as signal
can come and overwrite the memory. So maybe we should be invalidating
something at those instructions as well. But in leaf functions we certainly
can have even addressable automatic vars in the red zone (which would make
it harder to distinguish), on the other side aren't normally storing
anything below the red zone, and in non-leaf it should normally be just the
outgoing arguments area.
2025-02-05 Jakub Jelinek
PR rtl-optimization/117239
* cselib.cc: Include predict.h.
(callmem): Change type from rtx to rtx[2].
(cselib_preserve_only_values): Use callmem[0] rather than callmem.
(cselib_invalidate_mem): Optimize and don't try to invalidate
for the mem_rtx == callmem[1] case MEMs which clearly can't be
below the stack pointer.
(cselib_process_insn): Use callmem[0] rather than callmem.
For const/pure calls also call cselib_invalidate_mem (callmem[1])
in !ACCUMULATE_OUTGOING_ARGS or cfun->calls_alloca functions.
(cselib_init): Initialize callmem[0] rather than callmem and also
initialize callmem[1].
* gcc.dg/pr117239.c: New test.
(cherry picked from commit 886ce970eb096bb302228c891f0c8a889c79ad40)
diff --git a/gcc/cselib.cc b/gcc/cselib.cc
index 212d8a6c485..2382e994ebc 100644
--- a/gcc/cselib.cc
+++ b/gcc/cselib.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "cselib.h"
#include "function-abi.h"
#include "alias.h"
+#include "predict.h"
/* A list of cselib_val structures. */
struct elt_list
@@ -248,8 +249,9 @@ static unsigned int *used_regs;
static unsigned int n_used_regs;
/* We pass this to cselib_invalidate_mem to invalidate all of
- memory for a non-const call instruction. */
-static GTY(()) rtx callmem;
+ memory for a non-const call instruction and memory below stack pointer
+ for const/pure calls. */
+static GTY(()) rtx callmem[2];
/* Set by discard_useless_locs if it deleted the last location of any
value. */
@@ -808,7 +810,7 @@ cselib_preserve_only_values (void)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
cselib_invalidate_regno (i, reg_raw_mode[i]);
- cselib_invalidate_mem (callmem);
+ cselib_invalidate_mem (callmem[0]);
remove_useless_values ();
@@ -2600,6 +2602,8 @@ cselib_invalidate_mem (rtx mem_rtx)
struct elt_loc_list **p = &v->locs;
bool had_locs = v->locs != NULL;
rtx_insn *setting_insn = v->locs ? v->locs->setting_insn : NULL;
+ rtx sp_base = NULL_RTX;
+ HOST_WIDE_INT sp_off = 0;
while (*p)
{
@@ -2614,6 +2618,114 @@ cselib_invalidate_mem (rtx mem_rtx)
p = &(*p)->next;
continue;
}
+
+ /* When invalidating memory below the stack pointer for const/pure
+ calls and alloca/VLAs aren't used, attempt to optimize. Values
+ stored into area sometimes below the stack pointer shouldn't be
+ addressable and should be stored just through stack pointer
+ derived expressions, so don't invalidate MEMs not using stack
+ derived addresses, or if the MEMs clearly aren't below the stack
+ pointer. This isn't a fully conservative approach, the hope is
+ that invalidating more MEMs than this isn't actually needed. */
+ if (mem_rtx == callmem[1]
+ && num_mems < param_max_cselib_memory_locations
+ && GET_CODE (XEXP (x, 0)) == VALUE
+ && !cfun->calls_alloca)
+ {
+ cselib_val *v2 = CSELIB_VAL_PTR (XEXP (x, 0));
+ rtx x_base = NULL_RTX;
+ HOST_WIDE_INT x_off = 0;
+ if (SP_DERIVED_VALUE_P (v2->val_rtx))
+ x_base = v2->val_rtx;
+ else
+ for (struct elt_loc_list *l = v2->locs; l; l = l->next)
+ if (GET_CODE (l->loc) == PLUS
+ && GET_CODE (XEXP (l->loc, 0)) == VALUE
+ && SP_DERIVED_VALUE_P (XEXP (l->loc, 0))
+ && CONST_INT_P (XEXP (l->loc, 1)))
+ {
+ x_base = XEXP (l->loc, 0);
+ x_off = INTVAL (XEXP (l->loc, 1));
+ break;
+ }
+ /* If x_base is NULL here, don't invalidate x as its address
+ isn't derived from sp such that it could be in outgoing
+ argument area of some call in !ACCUMULATE_OUTGOING_ARGS
+ function. */
+ if (x_base)
+ {
+ if (sp_base == NULL_RTX)
+ {
+ if (cselib_val *v3
+ = cselib_lookup_1 (stack_pointer_rtx, Pmode, 0,
+ VOIDmode))
+ {
+ if (SP_DERIVED_VALUE_P (v3->val_rtx))
+ sp_base = v3->val_rtx;
+ else
+ for (struct elt_loc_list *l = v3->locs;
+ l; l = l->next)
+ if (GET_CODE (l->loc) == PLUS
+ && GET_CODE (XEXP (l->loc, 0)) == VALUE
+ && SP_DERIVED_VALUE_P (XEXP (l->loc, 0))
+ && CONST_INT_P (XEXP (l->loc, 1)))
+ {
+ sp_base = XEXP (l->loc, 0);
+ sp_off = INTVAL (XEXP (l->loc, 1));
+ break;
+ }
+ }
+ if (sp_base == NULL_RTX)
+ sp_base = pc_rtx;
+ }
+ /* Otherwise, if x_base and sp_base are the same,
+ we know that x_base + x_off is the x's address and
+ sp_base + sp_off is current value of stack pointer,
+ so try to determine if x is certainly not below stack
+ pointer. */
+ if (sp_base == x_base)
+ {
+ if (STACK_GROWS_DOWNWARD)
+ {
+ HOST_WIDE_INT off = sp_off;
+#ifdef STACK_ADDRESS_OFFSET
+ /* On SPARC take stack pointer bias into account as
+ well. */
+ off += (STACK_ADDRESS_OFFSET
+ - FIRST_PARM_OFFSET (current_function_decl));
+#endif
+ if (x_off >= off)
+ /* x is at or above the current stack pointer,
+ no need to invalidate it. */
+ x_base = NULL_RTX;
+ }
+ else
+ {
+ HOST_WIDE_INT sz;
+ enum machine_mode mode = GET_MODE (x);
+ if ((MEM_SIZE_KNOWN_P (x)
+ && MEM_SIZE (x).is_constant (&sz))
+ || (mode != BLKmode
+ && GET_MODE_SIZE (mode).is_constant (&sz)))
+ if (x_off < sp_off
+ && ((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT)
+ x_off + sz) <= sp_off))
+ /* x's end is below or at the current stack
+ pointer in !STACK_GROWS_DOWNWARD target,
+ no need to invalidate it. */
+ x_base = NULL_RTX;
+ }
+ }
+ }
+ if (x_base == NULL_RTX)
+ {
+ has_mem = true;
+ num_mems++;
+ p = &(*p)->next;
+ continue;
+ }
+ }
+
if (num_mems < param_max_cselib_memory_locations
&& ! canon_anti_dependence (x, false, mem_rtx,
GET_MODE (mem_rtx), mem_addr))
@@ -3166,14 +3278,24 @@ cselib_process_insn (rtx_insn *insn)
as if they were regular functions. */
if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
|| !(RTL_CONST_OR_PURE_CALL_P (insn)))
- cselib_invalidate_mem (callmem);
+ cselib_invalidate_mem (callmem[0]);
else
- /* For const/pure calls, invalidate any argument slots because
- they are owned by the callee. */
- for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
- if (GET_CODE (XEXP (x, 0)) == USE
- && MEM_P (XEXP (XEXP (x, 0), 0)))
- cselib_invalidate_mem (XEXP (XEXP (x, 0), 0));
+ {
+ /* For const/pure calls, invalidate any argument slots because
+ they are owned by the callee. */
+ for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
+ if (GET_CODE (XEXP (x, 0)) == USE
+ && MEM_P (XEXP (XEXP (x, 0), 0)))
+ cselib_invalidate_mem (XEXP (XEXP (x, 0), 0));
+ /* And invalidate memory below the stack (or above for
+ !STACK_GROWS_DOWNWARD), as even const/pure call can invalidate
+ that. Do this only if !ACCUMULATE_OUTGOING_ARGS or if
+ cfun->calls_alloca, otherwise the stack pointer shouldn't be
+ changing in the middle of the function and nothing should be
+ stored below the stack pointer. */
+ if (!ACCUMULATE_OUTGOING_ARGS || cfun->calls_alloca)
+ cselib_invalidate_mem (callmem[1]);
+ }
}
cselib_record_sets (insn);
@@ -3226,8 +3348,31 @@ cselib_init (int record_what)
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything,
see canon_true_dependence. This is only created once. */
- if (! callmem)
- callmem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
+ if (! callmem[0])
+ callmem[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
+ /* Similarly create a MEM representing roughly everything below
+ the stack for STACK_GROWS_DOWNWARD targets or everything above
+ it otherwise. Do this only when !ACCUMULATE_OUTGOING_ARGS or
+ if cfun->calls_alloca, otherwise the stack pointer shouldn't be
+ changing in the middle of the function and nothing should be stored
+ below the stack pointer. */
+ if (!callmem[1] && (!ACCUMULATE_OUTGOING_ARGS || cfun->calls_alloca))
+ {
+ if (STACK_GROWS_DOWNWARD)
+ {
+ unsigned HOST_WIDE_INT off = -(GET_MODE_MASK (Pmode) >> 1);
+#ifdef STACK_ADDRESS_OFFSET
+ /* On SPARC take stack pointer bias into account as well. */
+ off += (STACK_ADDRESS_OFFSET
+ - FIRST_PARM_OFFSET (current_function_decl)));
+#endif
+ callmem[1] = plus_constant (Pmode, stack_pointer_rtx, off);
+ }
+ else
+ callmem[1] = stack_pointer_rtx;
+ callmem[1] = gen_rtx_MEM (BLKmode, callmem[1]);
+ set_mem_size (callmem[1], GET_MODE_MASK (Pmode) >> 1);
+ }
cselib_nregs = max_reg_num ();
diff --git a/gcc/testsuite/gcc.dg/pr117239.c b/gcc/testsuite/gcc.dg/pr117239.c
new file mode 100644
index 00000000000..0ff33d19677
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr117239.c
@@ -0,0 +1,42 @@
+/* PR rtl-optimization/117239 */
+/* { dg-do run } */
+/* { dg-options "-fno-inline -O2" } */
+/* { dg-additional-options "-fschedule-insns" { target i?86-*-* x86_64-*-* } } */
+
+int a, b, c = 1, d;
+
+int
+foo (void)
+{
+ return a;
+}
+
+struct A {
+ int e, f, g, h;
+ short i;
+ int j;
+};
+
+void
+bar (int x, struct A y)
+{
+ if (y.j == 1)
+ c = 0;
+}
+
+int
+baz (struct A x)
+{
+ return b;
+}
+
+int
+main ()
+{
+ struct A k = { 0, 0, 0, 0, 0, 1 };
+ d = baz (k);
+ bar (foo (), k);
+ if (c != 0)
+ __builtin_abort ();
+ return 0;
+}
commit 5499c332a60a6928274796af0667d40719bf0715
Author: Jakub Jelinek
Date: Wed Feb 5 14:06:42 2025
cselib: Fix up previous patch for SPARC [PR117239]
Sorry, our CI bot just notified me I broke SPARC build. There are two
#ifdef STACK_ADDRESS_OFFSET
guarded snippets and the macro is only defined on SPARC target, so I didn't
notice there was a syntax error.
Fixed thusly.
2025-02-05 Jakub Jelinek
PR rtl-optimization/117239
* cselib.cc (cselib_init): Remove spurious closing paren in
the #ifdef STACK_ADDRESS_OFFSET specific code.
(cherry picked from commit 6094801d6fd7849d2d95ce78f7c6ef01686b9f63)
diff --git a/gcc/cselib.cc b/gcc/cselib.cc
index 2382e994ebc..f0a8f2c7f8f 100644
--- a/gcc/cselib.cc
+++ b/gcc/cselib.cc
@@ -3364,7 +3364,7 @@ cselib_init (int record_what)
#ifdef STACK_ADDRESS_OFFSET
/* On SPARC take stack pointer bias into account as well. */
off += (STACK_ADDRESS_OFFSET
- - FIRST_PARM_OFFSET (current_function_decl)));
+ - FIRST_PARM_OFFSET (current_function_decl));
#endif
callmem[1] = plus_constant (Pmode, stack_pointer_rtx, off);
}
commit 4b9f2877e334b4108c33259753acfdd27820b4f5
Author: Jakub Jelinek
Date: Thu Feb 27 08:48:18 2025
alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 [PR118819]
This PR is about ubsan error on the c - cx1 + cy1 evaluation in the first
hunk.
The following patch hopefully fixes that by doing the additions/subtractions
in poly_offset_int rather than poly_int64 and then converting back to poly_int64.
If it doesn't fit, -1 is returned (which means it is unknown if there is a conflict
or not).
2025-02-27 Jakub Jelinek
PR middle-end/118819
* alias.cc (memrefs_conflict_p): Perform arithmetics on c, xsize and
ysize in poly_offset_int and return -1 if it is not representable in
poly_int64.
(cherry picked from commit b570f48c3dfb9ca3d640467cff67e569904009d4)
diff --git a/gcc/alias.cc b/gcc/alias.cc
index 808e2095d9b..fab7161f694 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -2533,19 +2533,39 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
return memrefs_conflict_p (xsize, x1, ysize, y1, c);
if (poly_int_rtx_p (x1, &cx1))
{
+ poly_offset_int co = c;
+ co -= cx1;
if (poly_int_rtx_p (y1, &cy1))
- return memrefs_conflict_p (xsize, x0, ysize, y0,
- c - cx1 + cy1);
+ {
+ co += cy1;
+ if (!co.to_shwi (&c))
+ return -1;
+ return memrefs_conflict_p (xsize, x0, ysize, y0, c);
+ }
+ else if (!co.to_shwi (&c))
+ return -1;
else
- return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+ return memrefs_conflict_p (xsize, x0, ysize, y, c);
}
else if (poly_int_rtx_p (y1, &cy1))
- return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+ {
+ poly_offset_int co = c;
+ co += cy1;
+ if (!co.to_shwi (&c))
+ return -1;
+ return memrefs_conflict_p (xsize, x, ysize, y0, c);
+ }
return -1;
}
else if (poly_int_rtx_p (x1, &cx1))
- return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+ {
+ poly_offset_int co = c;
+ co -= cx1;
+ if (!co.to_shwi (&c))
+ return -1;
+ return memrefs_conflict_p (xsize, x0, ysize, y, c);
+ }
}
else if (GET_CODE (y) == PLUS)
{
@@ -2561,7 +2581,13 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
poly_int64 cy1;
if (poly_int_rtx_p (y1, &cy1))
- return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+ {
+ poly_offset_int co = c;
+ co += cy1;
+ if (!co.to_shwi (&c))
+ return -1;
+ return memrefs_conflict_p (xsize, x, ysize, y0, c);
+ }
else
return -1;
}
@@ -2614,8 +2640,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
if (maybe_gt (xsize, 0))
xsize = -xsize;
if (maybe_ne (xsize, 0))
- xsize += sc + 1;
- c -= sc + 1;
+ {
+ poly_offset_int xsizeo = xsize;
+ xsizeo += sc + 1;
+ if (!xsizeo.to_shwi (&xsize))
+ return -1;
+ }
+ poly_offset_int co = c;
+ co -= sc + 1;
+ if (!co.to_shwi (&c))
+ return -1;
return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
ysize, y, c);
}
@@ -2629,8 +2663,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
if (maybe_gt (ysize, 0))
ysize = -ysize;
if (maybe_ne (ysize, 0))
- ysize += sc + 1;
- c += sc + 1;
+ {
+ poly_offset_int ysizeo = ysize;
+ ysizeo += sc + 1;
+ if (!ysizeo.to_shwi (&ysize))
+ return -1;
+ }
+ poly_offset_int co = c;
+ co += sc + 1;
+ if (!co.to_shwi (&c))
+ return -1;
return memrefs_conflict_p (xsize, x,
ysize, canon_rtx (XEXP (y, 0)), c);
}
@@ -2641,7 +2683,11 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
poly_int64 cx, cy;
if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy))
{
- c += cy - cx;
+ poly_offset_int co = c;
+ co += cy;
+ co -= cx;
+ if (!co.to_shwi (&c))
+ return -1;
return offset_overlap_p (c, xsize, ysize);
}
commit 1dd54c5ad3930e27c4206ec3c08f4baecd9b4543
Author: Stefan Schulze Frielinghaus
Date: Wed May 14 09:22:00 2025
s390: Fix tf_to_fprx2
Insn tf_to_fprx2 moves a TF value into a floating-point register pair.
For alternative 0, the input is a vector register, however, in the else
case instruction ldr is emitted which expects floating-point register
operands only. Thus, this works only for vector registers which overlap
with floating-point registers. Replace ldr with vlr so that the
remaining vector registers are dealt with, too. Emitting a vlr instead
of a ldr is fine since the destination register %v0 is part of a
floating-point register pair which means that the low half of %v0 is
ignored in the end anyway and therefore may be clobbered.
gcc/ChangeLog:
* config/s390/vector.md: Fix tf_to_fprx2 by using vlr instead of
ldr.
(cherry picked from commit 8519b8ba9dd9567a5f90966351c1e758dbf511a4)
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 35defb7043a..a79f21b05c7 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -938,7 +938,7 @@
else
{
reg_pair += 2; // get rid of prefix %f
- snprintf (buf, sizeof (buf), "ldr\t%%f0,%%f1;vpdi\t%%%%v%s,%%v1,%%%%v%s,5", reg_pair, reg_pair);
+ snprintf (buf, sizeof (buf), "vlr\t%%v0,%%v1;vpdi\t%%%%v%s,%%v1,%%%%v%s,5", reg_pair, reg_pair);
output_asm_insn (buf, operands);
return "";
}
commit fb04c0409f668bcb4248ccfcdb512fb743b87d8e
Author: GCC Administrator
Date: Tue May 27 02:23:19 2025
Daily bump.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 541b6babe73..5796ada5214 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,83 @@
+2025-05-26 Stefan Schulze Frielinghaus
+
+ Backported from master:
+ 2025-05-14 Stefan Schulze Frielinghaus
+
+ * config/s390/vector.md: Fix tf_to_fprx2 by using vlr instead of
+ ldr.
+
+2025-05-26 Jakub Jelinek
+
+ Backported from master:
+ 2025-02-27 Jakub Jelinek
+
+ PR middle-end/118819
+ * alias.cc (memrefs_conflict_p): Perform arithmetics on c, xsize and
+ ysize in poly_offset_int and return -1 if it is not representable in
+ poly_int64.
+
+2025-05-26 Jakub Jelinek
+
+ Backported from master:
+ 2025-02-05 Jakub Jelinek
+
+ PR rtl-optimization/117239
+ * cselib.cc (cselib_init): Remove spurious closing paren in
+ the #ifdef STACK_ADDRESS_OFFSET specific code.
+
+2025-05-26 Jakub Jelinek
+
+ Backported from master:
+ 2025-02-05 Jakub Jelinek
+
+ PR rtl-optimization/117239
+ * cselib.cc: Include predict.h.
+ (callmem): Change type from rtx to rtx[2].
+ (cselib_preserve_only_values): Use callmem[0] rather than callmem.
+ (cselib_invalidate_mem): Optimize and don't try to invalidate
+ for the mem_rtx == callmem[1] case MEMs which clearly can't be
+ below the stack pointer.
+ (cselib_process_insn): Use callmem[0] rather than callmem.
+ For const/pure calls also call cselib_invalidate_mem (callmem[1])
+ in !ACCUMULATE_OUTGOING_ARGS or cfun->calls_alloca functions.
+ (cselib_init): Initialize callmem[0] rather than callmem and also
+ initialize callmem[1].
+
+2025-05-26 Jakub Jelinek
+
+ Backported from master:
+ 2024-11-28 Jakub Jelinek
+
+ PR tree-optimization/117358
+ * gimple-fold.cc (gimple_fold_builtin_memory_op): Punt if stmt has no
+ vdef in ssa form.
+ (gimple_fold_builtin_bcmp): Punt if stmt has no vuse in ssa form.
+ (gimple_fold_builtin_bcopy): Punt if stmt has no vdef in ssa form.
+ (gimple_fold_builtin_bzero): Likewise.
+ (gimple_fold_builtin_memset): Likewise. Use return false instead of
+ return NULL_TREE.
+ (gimple_fold_builtin_strcpy): Punt if stmt has no vdef in ssa form.
+ (gimple_fold_builtin_strncpy): Likewise.
+ (gimple_fold_builtin_strchr): Punt if stmt has no vuse in ssa form.
+ (gimple_fold_builtin_strstr): Likewise.
+ (gimple_fold_builtin_strcat): Punt if stmt has no vdef in ssa form.
+ (gimple_fold_builtin_strcat_chk): Likewise.
+ (gimple_fold_builtin_strncat): Likewise.
+ (gimple_fold_builtin_strncat_chk): Likewise.
+ (gimple_fold_builtin_string_compare): Likewise.
+ (gimple_fold_builtin_fputs): Likewise.
+ (gimple_fold_builtin_memory_chk): Likewise.
+ (gimple_fold_builtin_stxcpy_chk): Likewise.
+ (gimple_fold_builtin_stxncpy_chk): Likewise.
+ (gimple_fold_builtin_stpcpy): Likewise.
+ (gimple_fold_builtin_snprintf_chk): Likewise.
+ (gimple_fold_builtin_sprintf_chk): Likewise.
+ (gimple_fold_builtin_sprintf): Likewise.
+ (gimple_fold_builtin_snprintf): Likewise.
+ (gimple_fold_builtin_fprintf): Likewise.
+ (gimple_fold_builtin_printf): Likewise.
+ (gimple_fold_builtin_realloc): Likewise.
+
2025-05-25 Michael J. Eager
PR target/86772
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index dbf258be4a2..ed9a6b1f3e6 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250526
+20250527
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 23d940b9d1b..66360e6b9e9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,19 @@
+2025-05-26 Jakub Jelinek
+
+ Backported from master:
+ 2025-02-05 Jakub Jelinek
+
+ PR rtl-optimization/117239
+ * gcc.dg/pr117239.c: New test.
+
+2025-05-26 Jakub Jelinek
+
+ Backported from master:
+ 2024-11-28 Jakub Jelinek
+
+ PR tree-optimization/117358
+ * gcc.c-torture/compile/pr117358.c: New test.
+
2025-05-25 Harald Anlauf
Backported from master:
commit b380d260ba56b30cba7681c43e1b699d05152cdc
Author: Georg-Johann Lay
Date: Tue May 27 09:43:57 2025
AVR: target/120441 - Fix f7_exp for |x| ≥ 512.
f7_exp limited exponents to 512, but 1023 * ln2 ≈ 709,
hence 1024 is a correct limit.
libgcc/config/avr/libf7/
PR target/120441
* libf7.c (f7_exp): Limit aa->expo to 10 (not to 9).
(cherry picked from commit 672569cee76a1927d14b5eb754a5ff0b9cee1bc8)
diff --git a/libgcc/config/avr/libf7/libf7.c b/libgcc/config/avr/libf7/libf7.c
index 375becb854c..eb27dc7385d 100644
--- a/libgcc/config/avr/libf7/libf7.c
+++ b/libgcc/config/avr/libf7/libf7.c
@@ -1639,10 +1639,10 @@ void f7_exp (f7_t *cc, const f7_t *aa)
return f7_set_nan (cc);
/* The maximal exponent of 2 for a double is 1023, hence we may limit
- to |A| < 1023 * ln2 ~ 709. We limit to 1024 ~ 1.99 * 2^9 */
+ to |A| < 1023 * ln2 ~ 709. We limit to 1024 = 2^10 */
if (f7_class_inf (a_class)
- || (f7_class_nonzero (a_class) && aa->expo >= 9))
+ || (f7_class_nonzero (a_class) && aa->expo >= 10))
{
if (f7_class_sign (a_class))
return f7_clr (cc);
commit 85f466ed0d4da336fadd01e43d764326cbabdecb
Author: Patrick Palka
Date: Thu May 15 17:07:53 2025
c++: unifying specializations of non-primary tmpls [PR120161]
Here unification of P=Wrap::type, A=Wrap::type wrongly
succeeds ever since r14-4112 which made the RECORD_TYPE case of unify
no longer recurse into template arguments for non-primary templates
(since they're a non-deduced context) and so the int/long mismatch that
makes the two types distinct goes unnoticed.
In the case of (comparing specializations of) a non-primary template,
unify should still go on to compare the types directly before returning
success.
PR c++/120161
gcc/cp/ChangeLog:
* pt.cc (unify) : When comparing specializations
of a non-primary template, still perform a type comparison.
gcc/testsuite/ChangeLog:
* g++.dg/template/unify13.C: New test.
Reviewed-by: Jason Merrill
(cherry picked from commit 0c430503f2849ebb20105695b8ad40d43d797c7b)
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 65fa85b0610..fb9b407c453 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -25299,10 +25299,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (parm)),
INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (t)),
UNIFY_ALLOW_NONE, explain_p);
- else
- return unify_success (explain_p);
+ gcc_checking_assert (t == arg);
}
- else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg))
+
+ if (!same_type_ignoring_top_level_qualifiers_p (parm, arg))
return unify_type_mismatch (explain_p, parm, arg);
return unify_success (explain_p);
diff --git a/gcc/testsuite/g++.dg/template/unify13.C b/gcc/testsuite/g++.dg/template/unify13.C
new file mode 100644
index 00000000000..ec7ca9d17a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/unify13.C
@@ -0,0 +1,18 @@
+// PR c++/120161
+
+template
+struct mp_list { };
+
+template
+struct Wrap { struct type { }; };
+
+struct A : mp_list::type, void>
+ , mp_list::type, void> { };
+
+template
+void f(mp_list::type, U>*);
+
+int main() {
+ A a;
+ f(&a);
+}
commit 4035c5bb55ea3ae9e249a7aebaf08039346a3e16
Author: GCC Administrator
Date: Wed May 28 02:22:29 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index ed9a6b1f3e6..4044138c536 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250527
+20250528
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 14599c44fb8..56acd079690 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2025-05-27 Patrick Palka
+
+ Backported from master:
+ 2025-05-15 Patrick Palka
+
+ PR c++/120161
+ * pt.cc (unify) : When comparing specializations
+ of a non-primary template, still perform a type comparison.
+
2025-05-23 Release Manager
* GCC 14.3.0 released.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 66360e6b9e9..7e4bb673cfb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2025-05-27 Patrick Palka
+
+ Backported from master:
+ 2025-05-15 Patrick Palka
+
+ PR c++/120161
+ * g++.dg/template/unify13.C: New test.
+
2025-05-26 Jakub Jelinek
Backported from master:
diff --git a/libgcc/config/avr/libf7/ChangeLog b/libgcc/config/avr/libf7/ChangeLog
index e8474b76d1e..c7dc1d93868 100644
--- a/libgcc/config/avr/libf7/ChangeLog
+++ b/libgcc/config/avr/libf7/ChangeLog
@@ -1,3 +1,11 @@
+2025-05-27 Georg-Johann Lay
+
+ Backported from master:
+ 2025-05-27 Georg-Johann Lay
+
+ PR target/120441
+ * libf7.c (f7_exp): Limit aa->expo to 10 (not to 9).
+
2025-05-23 Release Manager
* GCC 14.3.0 released.
commit a153c6f9345a3f6cc8094020510121e9a7d9780a
Author: GCC Administrator
Date: Thu May 29 02:22:59 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 4044138c536..939851372b3 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250528
+20250529
commit 7f564d0d8caa32c38cb8efd89c1bb5bf631ef041
Author: GCC Administrator
Date: Fri May 30 02:23:53 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 939851372b3..ac274333576 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250529
+20250530
commit 004bbbb523c9530f94ae3d64d4c9967ff90388bc
Author: Jakub Jelinek
Date: Thu Apr 17 10:57:18 2025
s390: Use match_scratch instead of scratch in define_split [PR119834]
The following testcase ICEs since r15-1579 (addition of late combiner),
because *clrmem_short can't be split.
The problem is that the define_insn uses
(use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
(use (match_operand 2 "immediate_operand" "X,R,X,X"))
(clobber (match_scratch:P 3 "=X,X,X,&a"))
and define_split assumed that if operands[1] is const_int_operand,
match_scratch will be always scratch, and it will be reg only if
it was the last alternative where operands[1] is a reg.
The pattern doesn't guarantee it though, of course RA will not try to
uselessly assign a reg there if it is not needed, but during RA
on the testcase below we match the last alternative, but then comes
late combiner and propagates const_int 3 into operands[1]. And that
matches fine, match_scratch matches either scratch or reg and the constraint
in that case is X for the first variant, so still just fine. But we won't
split that because the splitters only expect scratch.
The following patch fixes it by using match_scratch instead of scratch,
so that it accepts either.
2025-04-17 Jakub Jelinek
PR target/119834
* config/s390/s390.md (define_split after *cpymem_short): Use
(clobber (match_scratch N)) instead of (clobber (scratch)). Use
(match_dup 4) and operands[4] instead of (match_dup 3) and operands[3]
in the last of those.
(define_split after *clrmem_short): Use (clobber (match_scratch N))
instead of (clobber (scratch)).
(define_split after *cmpmem_short): Likewise.
* g++.target/s390/pr119834.C: New test.
(cherry picked from commit 22fe83d6fc9f59311241c981bcad58b61e2056d4)
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 72e05be9b18..c364880af0a 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3392,7 +3392,7 @@
(match_operand:BLK 1 "memory_operand" ""))
(use (match_operand 2 "const_int_operand" ""))
(use (match_operand 3 "immediate_operand" ""))
- (clobber (scratch))]
+ (clobber (match_scratch 4))]
"reload_completed"
[(parallel
[(set (match_dup 0) (match_dup 1))
@@ -3404,7 +3404,7 @@
(match_operand:BLK 1 "memory_operand" ""))
(use (match_operand 2 "register_operand" ""))
(use (match_operand 3 "memory_operand" ""))
- (clobber (scratch))]
+ (clobber (match_scratch 4))]
"reload_completed"
[(parallel
[(unspec [(match_dup 2) (match_dup 3)
@@ -3418,14 +3418,14 @@
(match_operand:BLK 1 "memory_operand" ""))
(use (match_operand 2 "register_operand" ""))
(use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
- (clobber (scratch))]
+ (clobber (match_scratch 3))]
"TARGET_Z10 && reload_completed"
[(parallel
[(unspec [(match_dup 2) (const_int 0)
- (label_ref (match_dup 3))] UNSPEC_EXECUTE)
+ (label_ref (match_dup 4))] UNSPEC_EXECUTE)
(set (match_dup 0) (match_dup 1))
(use (const_int 1))])]
- "operands[3] = gen_label_rtx ();")
+ "operands[4] = gen_label_rtx ();")
(define_split
[(set (match_operand:BLK 0 "memory_operand" "")
@@ -3644,7 +3644,7 @@
(const_int 0))
(use (match_operand 1 "const_int_operand" ""))
(use (match_operand 2 "immediate_operand" ""))
- (clobber (scratch))
+ (clobber (match_scratch 3))
(clobber (reg:CC CC_REGNUM))]
"reload_completed"
[(parallel
@@ -3658,7 +3658,7 @@
(const_int 0))
(use (match_operand 1 "register_operand" ""))
(use (match_operand 2 "memory_operand" ""))
- (clobber (scratch))
+ (clobber (match_scratch 3))
(clobber (reg:CC CC_REGNUM))]
"reload_completed"
[(parallel
@@ -3674,7 +3674,7 @@
(const_int 0))
(use (match_operand 1 "register_operand" ""))
(use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
- (clobber (scratch))
+ (clobber (match_scratch 2))
(clobber (reg:CC CC_REGNUM))]
"TARGET_Z10 && reload_completed"
[(parallel
@@ -3839,7 +3839,7 @@
(match_operand:BLK 1 "memory_operand" "")))
(use (match_operand 2 "const_int_operand" ""))
(use (match_operand 3 "immediate_operand" ""))
- (clobber (scratch))]
+ (clobber (match_scratch 4))]
"reload_completed"
[(parallel
[(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
@@ -3852,7 +3852,7 @@
(match_operand:BLK 1 "memory_operand" "")))
(use (match_operand 2 "register_operand" ""))
(use (match_operand 3 "memory_operand" ""))
- (clobber (scratch))]
+ (clobber (match_scratch 4))]
"reload_completed"
[(parallel
[(unspec [(match_dup 2) (match_dup 3)
@@ -3867,7 +3867,7 @@
(match_operand:BLK 1 "memory_operand" "")))
(use (match_operand 2 "register_operand" ""))
(use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
- (clobber (scratch))]
+ (clobber (match_scratch 3))]
"TARGET_Z10 && reload_completed"
[(parallel
[(unspec [(match_dup 2) (const_int 0)
diff --git a/gcc/testsuite/g++.target/s390/pr119834.C b/gcc/testsuite/g++.target/s390/pr119834.C
new file mode 100644
index 00000000000..66c0a69a1c1
--- /dev/null
+++ b/gcc/testsuite/g++.target/s390/pr119834.C
@@ -0,0 +1,76 @@
+// PR target/119834
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -march=z900" }
+
+int *a;
+struct A;
+struct B {
+ A begin ();
+ A end ();
+ operator bool * ();
+ void operator++ ();
+};
+template
+auto operator| (int, T x) -> decltype (x (0));
+struct A : B { bool a; };
+struct C { A operator () (int); };
+enum D {} d;
+int e;
+void foo ();
+struct E {
+ template
+ T *garply ()
+ {
+ if (d)
+ return 0;
+ if (e)
+ foo ();
+ return reinterpret_cast (f);
+ }
+ template
+ void bar (long x, bool)
+ {
+ if (&g - f)
+ __builtin_memset (a, 0, x);
+ f += x;
+ }
+ template
+ T *baz (T *x, long y, bool z = true)
+ {
+ if (d)
+ return nullptr;
+ bar ((char *)x + y - f, z);
+ return x;
+ }
+ template
+ void qux (T x) { baz (x, x->j); }
+ char *f, g;
+} *h;
+struct F {
+ template
+ int corge (T x) { x.freddy (this); return 0; }
+ template
+ int boo (T x) { corge (x); return 0; }
+} i;
+template
+struct G {
+ template friend T operator+ (U, G);
+ template
+ void waldo (F *x, G y, U z) { x->boo (z + y); }
+ template
+ void plugh (E *y, Ts... z) { T *x = y->garply (); x->thud (y, z...); }
+};
+template using H = G;
+struct I {
+ static constexpr unsigned j = 2;
+ void thud (E *x, A y) { x->qux (this); for (auto g : y) ; }
+};
+H k;
+struct J {
+ void freddy (F *) { C a; auto b = 0 | a; k.plugh (h, b); }
+};
+H l;
+struct K {
+ void freddy () { l.waldo (&i, l, this); }
+};
+void grault () { K m; m.freddy (); }
commit f4def864a27c41025bbed0d086fa4628921fec28
Author: Jakub Jelinek
Date: Fri May 30 14:35:12 2025
testsuite: Add testcase for GCC 13 branch s390 bug [PR120480]
This got broken with r13-9727 and fixed with either of
r13-9729 or r13-9728.
2025-05-30 Jakub Jelinek
PR target/120480
* gcc.dg/pr120480.c: New test.
(cherry picked from commit c13d5b939fee565047394475952878dc5394fb74)
diff --git a/gcc/testsuite/gcc.dg/pr120480.c b/gcc/testsuite/gcc.dg/pr120480.c
new file mode 100644
index 00000000000..cf7b47a1151
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr120480.c
@@ -0,0 +1,11 @@
+/* PR target/120480 */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+struct S { int a, b, c; } s;
+
+void
+foo (void)
+{
+ struct S t = s;
+}
commit 5c72c410dd18a7f809ee90273f1cc8fbe8827d56
Author: GCC Administrator
Date: Sat May 31 02:24:12 2025
Daily bump.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5796ada5214..adde1e3b090 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2025-05-30 Jakub Jelinek
+
+ Backported from master:
+ 2025-04-17 Jakub Jelinek
+
+ PR target/119834
+ * config/s390/s390.md (define_split after *cpymem_short): Use
+ (clobber (match_scratch N)) instead of (clobber (scratch)). Use
+ (match_dup 4) and operands[4] instead of (match_dup 3) and operands[3]
+ in the last of those.
+ (define_split after *clrmem_short): Use (clobber (match_scratch N))
+ instead of (clobber (scratch)).
+ (define_split after *cmpmem_short): Likewise.
+
2025-05-26 Stefan Schulze Frielinghaus
Backported from master:
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index ac274333576..e844ed6f555 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250530
+20250531
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7e4bb673cfb..7a0e53823a2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,19 @@
+2025-05-30 Jakub Jelinek
+
+ Backported from master:
+ 2025-05-30 Jakub Jelinek
+
+ PR target/120480
+ * gcc.dg/pr120480.c: New test.
+
+2025-05-30 Jakub Jelinek
+
+ Backported from master:
+ 2025-04-17 Jakub Jelinek
+
+ PR target/119834
+ * g++.target/s390/pr119834.C: New test.
+
2025-05-27 Patrick Palka
Backported from master:
commit abab6fed80e06432468e9d7441375f19ce5ed9a4
Author: GCC Administrator
Date: Sun Jun 1 02:24:11 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index e844ed6f555..42f5016bedf 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250531
+20250601
commit e02b12e7248f8209ebad35d6df214d3421ed8020
Author: GCC Administrator
Date: Mon Jun 2 02:22:10 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 42f5016bedf..5646e6e7423 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250601
+20250602
commit 6e10db3be0193514d8a67d1367d8fbe639e03b6a
Author: Jason Merrill
Date: Sat May 31 00:27:45 2025
c++: lambda this capture and requires [PR120123]
We shouldn't need to be within the lambda body to look through it to the
enclosing non-static member function.
This change is a small subset of r16-970.
PR c++/120123
gcc/cp/ChangeLog:
* lambda.cc (nonlambda_method_basetype): Look through lambdas
even when current_class_ref is null.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-lambda24.C: New test.
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index 5c97f0f6fd3..dfaf79692cd 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1002,12 +1002,9 @@ current_nonlambda_function (void)
tree
nonlambda_method_basetype (void)
{
- if (!current_class_ref)
- return NULL_TREE;
-
tree type = current_class_type;
if (!type || !LAMBDA_TYPE_P (type))
- return type;
+ return current_class_ref ? type : NULL_TREE;
while (true)
{
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda24.C b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda24.C
new file mode 100644
index 00000000000..28f56ca2335
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda24.C
@@ -0,0 +1,13 @@
+// PR c++/120123
+// { dg-do compile { target c++20 } }
+
+struct H {
+ void member(int) {}
+ void call() {
+ [this]() {
+ [this](const auto& v)
+ requires requires { /*this->*/member(v); }
+ { return member(v); }(0);
+ };
+ }
+};
commit 42e99e057bd7cea8be374e1a47f0dfbf77974f88
Author: GCC Administrator
Date: Tue Jun 3 02:23:56 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 5646e6e7423..42c54799b73 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250602
+20250603
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 56acd079690..233f9ed881a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2025-06-02 Jason Merrill
+
+ PR c++/120123
+ * lambda.cc (nonlambda_method_basetype): Look through lambdas
+ even when current_class_ref is null.
+
2025-05-27 Patrick Palka
Backported from master:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7a0e53823a2..d5ee8b038d9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2025-06-02 Jason Merrill
+
+ PR c++/120123
+ * g++.dg/cpp2a/concepts-lambda24.C: New test.
+
2025-05-30 Jakub Jelinek
Backported from master:
commit e87f1871cfd5d0dd0860fe525ea5ec435d037ea0
Author: GCC Administrator
Date: Wed Jun 4 02:26:17 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 42c54799b73..932c2dd9fa2 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250603
+20250604
commit 3a2454f578c208d5944a076800201c4452a4ef52
Author: GCC Administrator
Date: Thu Jun 5 02:25:26 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 932c2dd9fa2..520e78d7696 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250604
+20250605
commit 317ff8a8eadfaae6d484dc328277ade42b352342
Author: Eric Botcazou
Date: Thu Jun 5 13:20:26 2025
Fix crash with constant initializer caused by IPA
The testcase compiled with -O2 -gnatn makes the compiler crash in
vect_can_force_dr_alignment_p during SLP vectorization:
if (decl_in_symtab_p (decl)
&& !symtab_node::get (decl)->can_increase_alignment_p ())
return false;
because symtab_node::get (decl) returns a null node. The phenomenon occurs
for a pair of twin symbols listed like so in .cgraph:
Opt7_Pkg.T12b/17 (Opt7_Pkg.T12b)
Type: variable definition analyzed
Visibility: semantic_interposition external public artificial
Aux: @0x44d45e0
References:
Referring: opt7_pkg__enum_name_table/13 (addr) opt7_pkg__enum_name_table/13
(addr)
Availability: not-ready
Varpool flags: initialized read-only const-value-known
Opt7_Pkg.T8b/16 (Opt7_Pkg.T8b)
Type: variable definition analyzed
Visibility: semantic_interposition external public artificial
Aux: @0x7f9fda3fff00
References:
Referring: opt7_pkg__enum_name_table/13 (addr) opt7_pkg__enum_name_table/13
(addr)
Availability: not-ready
Varpool flags: initialized read-only const-value-known
with:
opt7_pkg__enum_name_table/13 (Opt7_Pkg.Enum_Name_Table)
Type: variable definition analyzed
Visibility: semantic_interposition external public
Aux: @0x44d45e0
References: Opt7_Pkg.T8b/16 (addr) Opt7_Pkg.T8b/16 (addr) Opt7_Pkg.T12b/17
(addr) Opt7_Pkg.T12b/17 (addr)
Referring: opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
opt7_pkg__image/2 (read) opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
opt7_pkg__image/2 (read) opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
Availability: not-ready
Varpool flags: initialized read-only const-value-known
being the crux of the matter.
What happens is that symtab_remove_unreachable_nodes leaves the last symbol
in kind of a limbo state: in .remove_symbols, we have:
opt7_pkg__enum_name_table/13 (Opt7_Pkg.Enum_Name_Table)
Type: variable
Body removed by symtab_remove_unreachable_nodes
Visibility: externally_visible semantic_interposition external public
References:
Referring: opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
Availability: not_available
Varpool flags: initialized read-only const-value-known
This means that the "body" (DECL_INITIAL) of the symbol has been disregarded
during reachability analysis, causing the first two symbols to be discarded:
Reclaiming variables: Opt7_Pkg.T12b/17 Opt7_Pkg.T8b/16
but the DECL_INITIAL is explicitly preserved for later constant folding,
which makes it possible to retrofit the DECLs corresponding to the first
two symbols in the GIMPLE IR and ultimately leads to the crash.
gcc/
* tree-vect-data-refs.cc (vect_can_force_dr_alignment_p): Return
false if the variable has no symtab node.
gcc/testsuite/
* gnat.dg/specs/opt7.ads: New test.
* gnat.dg/specs/opt7_pkg.ads: New helper.
* gnat.dg/specs/opt7_pkg.adb: Likewise.
diff --git a/gcc/testsuite/gnat.dg/specs/opt7.ads b/gcc/testsuite/gnat.dg/specs/opt7.ads
new file mode 100644
index 00000000000..ee151f082a8
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt7.ads
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -gnatn" }
+
+with Opt7_Pkg; use Opt7_Pkg;
+
+package Opt7 is
+
+ type Rec is record
+ E : Enum;
+ end record;
+
+ function Image (R : Rec) return String is
+ (if R.E = A then Image (R.E) else "");
+
+end Opt7;
diff --git a/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb b/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb
new file mode 100644
index 00000000000..1c9d79bb872
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb
@@ -0,0 +1,15 @@
+package body Opt7_Pkg is
+
+ type Constant_String_Access is access constant String;
+
+ type Enum_Name is array (Enum) of Constant_String_Access;
+
+ Enum_Name_Table : constant Enum_Name :=
+ (A => new String'("A"), B => new String'("B"));
+
+ function Image (E : Enum) return String is
+ begin
+ return Enum_Name_Table (E).all;
+ end Image;
+
+end Opt7_Pkg;
diff --git a/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads b/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads
new file mode 100644
index 00000000000..2dd271b63ad
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads
@@ -0,0 +1,9 @@
+-- { dg-excess-errors "no code generated" }
+
+package Opt7_Pkg is
+
+ type Enum is (A, B);
+
+ function Image (E : Enum) return String with Inline;
+
+end Opt7_Pkg;
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index cae154af6dd..dff6db794b0 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -7058,7 +7058,8 @@ vect_can_force_dr_alignment_p (const_tree decl, poly_uint64 alignment)
return false;
if (decl_in_symtab_p (decl)
- && !symtab_node::get (decl)->can_increase_alignment_p ())
+ && (!symtab_node::get (decl)
+ || !symtab_node::get (decl)->can_increase_alignment_p ()))
return false;
if (TREE_STATIC (decl))
commit d0c4f654354a7e4324a18d06860d1af4963fb658
Author: Giuseppe D'Angelo
Date: Tue Dec 10 00:56:13 2024
libstdc++: fix compile error when converting std::weak_ptr
A std::weak_ptr can be converted to a compatible
std::weak_ptr. This is implemented by having suitable converting
constructors to std::weak_ptr which dispatch to the __weak_ptr base
class (implementation detail).
In __weak_ptr, lock() is supposed to return a __shared_ptr,
not a __shared_ptr (that is, __shared_ptr).
Unfortunately the return type of lock() and the type of the returned
__shared_ptr were mismatching and that was causing a compile error: when
converting a __weak_ptr to a __weak_ptr through __weak_ptr's
converting constructor, the code calls lock(), and that simply fails to
build.
Fix it by removing the usage of element_type inside lock(), and using
_Tp instead.
Note that std::weak_ptr::lock() itself was already correct; the one in
__weak_ptr was faulty (and that is the one called by __weak_ptr's
converting constructors).
libstdc++-v3/ChangeLog:
* include/bits/shared_ptr_base.h (lock): Fixed a compile error
when calling lock() on a weak_ptr, by removing an
erroneous usage of element_type from within lock().
* testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc:
Add more tests for array types.
* testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc:
Likewise.
* testsuite/20_util/shared_ptr/requirements/1.cc: New test.
* testsuite/20_util/weak_ptr/requirements/1.cc: New test.
(cherry picked from commit df0e6509bf74421ea68a2e025300bcd6ca63722f)
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
index 3d0b74ba1c6..397763f2723 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -2069,7 +2069,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__shared_ptr<_Tp, _Lp>
lock() const noexcept
- { return __shared_ptr(*this, std::nothrow); }
+ { return __shared_ptr<_Tp, _Lp>(*this, std::nothrow); }
long
use_count() const noexcept
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/1.cc
new file mode 100644
index 00000000000..8ddb5d220ac
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/1.cc
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target hosted }
+
+#include
+#include
+
+using namespace __gnu_test;
+
+void
+test01()
+{
+ std::shared_ptr ptr;
+ std::shared_ptr ptr2 = ptr;
+
+#if __cpp_lib_shared_ptr_arrays >= 201611L
+ std::shared_ptr ptr_array;
+ std::shared_ptr ptr_array2 = ptr_array;
+ std::shared_ptr ptr_array3 = ptr_array;
+#endif
+}
+
+void
+test02()
+{
+ std::shared_ptr ptr;
+ std::shared_ptr ptr2 = ptr;
+
+#if __cpp_lib_shared_ptr_arrays >= 201611L
+ std::shared_ptr ptr_array;
+ std::shared_ptr ptr_array2 = ptr_array;
+ std::shared_ptr ptr_array3 = ptr_array;
+#endif
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc
index 94bc8c7adfe..48f162d4072 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc
@@ -28,3 +28,15 @@ template class std::shared_ptr;
template class std::shared_ptr;
template class std::shared_ptr;
template class std::shared_ptr;
+
+#if __cpp_lib_shared_ptr_arrays >= 201611L
+template class std::shared_ptr;
+template class std::shared_ptr;
+template class std::shared_ptr;
+template class std::shared_ptr;
+
+template class std::shared_ptr;
+template class std::shared_ptr;
+template class std::shared_ptr;
+template class std::shared_ptr;
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/1.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/1.cc
new file mode 100644
index 00000000000..04ea837d85a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/1.cc
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target hosted }
+
+#include
+#include
+
+using namespace __gnu_test;
+
+void
+test01()
+{
+ std::weak_ptr ptr;
+ std::weak_ptr ptr2 = ptr;
+
+#if __cpp_lib_shared_ptr_arrays >= 201611L
+ std::weak_ptr ptr_array;
+ std::weak_ptr ptr_array2 = ptr_array;
+ std::weak_ptr ptr_array3 = ptr_array;
+#endif
+}
+
+void
+test02()
+{
+ std::weak_ptr ptr;
+ std::weak_ptr ptr2 = ptr;
+
+#if __cpp_lib_shared_ptr_arrays >= 201611L
+ std::weak_ptr ptr_array;
+ std::weak_ptr ptr_array2 = ptr_array;
+ std::weak_ptr ptr_array3 = ptr_array;
+#endif
+}
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc
index b32ff6ea284..b51a614693c 100644
--- a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc
@@ -28,3 +28,15 @@ template class std::weak_ptr;
template class std::weak_ptr;
template class std::weak_ptr;
template class std::weak_ptr;
+
+#if __cpp_lib_shared_ptr_arrays >= 201611L
+template class std::weak_ptr;
+template class std::weak_ptr;
+template class std::weak_ptr;
+template class std::weak_ptr;
+
+template class std::weak_ptr;
+template class std::weak_ptr;
+template class std::weak_ptr;
+template class std::weak_ptr;
+#endif
commit cf7cb901d7ba3e5d7475d774c42dc5609f91b558
Author: GCC Administrator
Date: Fri Jun 6 02:24:04 2025
Daily bump.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index adde1e3b090..de534a66c31 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2025-06-05 Eric Botcazou
+
+ * tree-vect-data-refs.cc (vect_can_force_dr_alignment_p): Return
+ false if the variable has no symtab node.
+
2025-05-30 Jakub Jelinek
Backported from master:
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 520e78d7696..c6de4e34998 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250605
+20250606
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d5ee8b038d9..89e6da052e2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2025-06-05 Eric Botcazou
+
+ * gnat.dg/specs/opt7.ads: New test.
+ * gnat.dg/specs/opt7_pkg.ads: New helper.
+ * gnat.dg/specs/opt7_pkg.adb: Likewise.
+
2025-06-02 Jason Merrill
PR c++/120123
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 9a126107f5e..c4bf363c695 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,18 @@
+2025-06-05 Giuseppe D'Angelo
+
+ Backported from master:
+ 2025-03-14 Giuseppe D'Angelo
+
+ * include/bits/shared_ptr_base.h (lock): Fixed a compile error
+ when calling lock() on a weak_ptr, by removing an
+ erroneous usage of element_type from within lock().
+ * testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc:
+ Add more tests for array types.
+ * testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc:
+ Likewise.
+ * testsuite/20_util/shared_ptr/requirements/1.cc: New test.
+ * testsuite/20_util/weak_ptr/requirements/1.cc: New test.
+
2025-05-23 Release Manager
* GCC 14.3.0 released.
commit efdddc8d6a0d175eb2c74a7feb7758bd04f69b11
Author: GCC Administrator
Date: Sat Jun 7 02:24:23 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index c6de4e34998..a3a91b55b0f 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250606
+20250607
commit 4a82b78552a62a90ac2b82893c2f6b99e59c0bc5
Author: GCC Administrator
Date: Sun Jun 8 02:22:41 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index a3a91b55b0f..800deb1dc5a 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250607
+20250608
commit e1a6f6dd2d3f1bccd1a471509bd94b4a48688be7
Author: GCC Administrator
Date: Mon Jun 9 02:23:11 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 800deb1dc5a..d0f154b4f06 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250608
+20250609
commit 4a46af97f5e2bb8d6ac2af0735d25d0c8464723c
Author: GCC Administrator
Date: Tue Jun 10 02:24:17 2025
Daily bump.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index d0f154b4f06..52988ae3b03 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250609
+20250610
commit e1cbf566970f02a7ac110df58c412be11604b278
Author: Jonathan Wakely
Date: Tue May 20 11:53:41 2025
libstdc++: Fix incorrect links to archived SGI STL docs
In r8-7777-g25949ee33201f2 I updated some URLs to point to copies of the
SGI STL docs in the Wayback Machine, because the original pags were no
longer hosted on sgi.com. However, I incorrectly assumed that if one
archived page was at https://web.archive.org/web/20171225062613/... then
all the other pages would be too. Apparently that's not how the Wayback
Machine works, and each page is archived on a different date. That meant
that some of our links were redirecting to archived copies of the
announcement that the SGI STL docs have gone away.
This fixes each URL to refer to a correctly archived copy of the
original docs.
libstdc++-v3/ChangeLog:
* doc/xml/faq.xml: Update URL for archived SGI STL docs.
* doc/xml/manual/containers.xml: Likewise.
* doc/xml/manual/extensions.xml: Likewise.
* doc/xml/manual/using.xml: Likewise.
* doc/xml/manual/utilities.xml: Likewise.
* doc/html/*: Regenerate.
(cherry picked from commit 501e6e786652748ff0ad9a322f74b9b47970031f)
diff --git a/libstdc++-v3/doc/html/faq.html b/libstdc++-v3/doc/html/faq.html
index bbe716d5e23..62213793933 100644
--- a/libstdc++-v3/doc/html/faq.html
+++ b/libstdc++-v3/doc/html/faq.html
@@ -796,7 +796,7 @@
Libstdc++-v3 incorporates a lot of code from
the SGI STL
(the final merge was from
- release 3.3).
+ release 3.3).
The code in libstdc++ contains many fixes and changes compared to the
original SGI code.
diff --git a/libstdc++-v3/doc/html/manual/containers.html b/libstdc++-v3/doc/html/manual/containers.html
index 7035a949074..dcd609a6000 100644
--- a/libstdc++-v3/doc/html/manual/containers.html
+++ b/libstdc++-v3/doc/html/manual/containers.html
@@ -11,7 +11,7 @@
Yes it is, at least using the old
ABI, and that's okay. This is a decision that we preserved
when we imported SGI's STL implementation. The following is
- quoted from their FAQ:
+ quoted from their FAQ:
The size() member function, for list and slist, takes time
proportional to the number of elements in the list. This was a
diff --git a/libstdc++-v3/doc/html/manual/ext_numerics.html b/libstdc++-v3/doc/html/manual/ext_numerics.html
index 9b864e1dcf4..c3a5623d175 100644
--- a/libstdc++-v3/doc/html/manual/ext_numerics.html
+++ b/libstdc++-v3/doc/html/manual/ext_numerics.html
@@ -14,7 +14,7 @@
The operation functor must be associative.
The iota function wins the award for Extension With the
Coolest Name (the name comes from Ken Iverson's APL language.) As
- described in the SGI
+ described in the SGI
documentation, it "assigns sequentially increasing values to a range.
That is, it assigns value to *first,
value + 1 to *(first + 1) and so on."
diff --git a/libstdc++-v3/doc/html/manual/ext_sgi.html b/libstdc++-v3/doc/html/manual/ext_sgi.html
index ae2062954f4..2310857804b 100644
--- a/libstdc++-v3/doc/html/manual/ext_sgi.html
+++ b/libstdc++-v3/doc/html/manual/ext_sgi.html
@@ -28,12 +28,12 @@
and sets.
Each of the associative containers map, multimap, set, and multiset
have a counterpart which uses a
- hashing
+ hashing
function to do the arranging, instead of a strict weak ordering
function. The classes take as one of their template parameters a
function object that will return the hash value; by default, an
instantiation of
- hash.
+ hash.
You should specialize this functor for your class, or define your own,
before trying to use one of the hashing classes.
The hashing classes support all the usual associative container
diff --git a/libstdc++-v3/doc/html/manual/using_concurrency.html b/libstdc++-v3/doc/html/manual/using_concurrency.html
index f99cca414ec..a75adbf0f22 100644
--- a/libstdc++-v3/doc/html/manual/using_concurrency.html
+++ b/libstdc++-v3/doc/html/manual/using_concurrency.html
@@ -40,7 +40,7 @@ The standard places requirements on the library to ensure that no data
races are caused by the library itself or by programs which use the
library correctly (as described below).
The C++11 memory model and library requirements are a more formal version
-of the SGI STL definition of thread safety, which the library used
+of the SGI STL definition of thread safety, which the library used
prior to the 2011 standard.
The library strives to be thread-safe when all of the following
conditions are met:
@@ -243,10 +243,10 @@ gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)
threaded and non-threaded code), see Chapter 17.
Two excellent pages to read when working with the Standard C++
containers and threads are
- SGI's
- https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/thread_safety.html and
- SGI's
- https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/Allocators.html.
+ SGI's
+ https://web.archive.org/web/20171221154911/http://www.sgi.com/tech/stl/thread_safety.html and
+ SGI's
+ https://web.archive.org/web/20171108142526/http://www.sgi.com/tech/stl/Allocators.html.
However, please ignore all discussions about the user-level
configuration of the lock implementation inside the STL
container-memory allocator on those pages. For the sake of this
diff --git a/libstdc++-v3/doc/html/manual/utilities.html b/libstdc++-v3/doc/html/manual/utilities.html
index 15c9a9d170a..1216b72ad3e 100644
--- a/libstdc++-v3/doc/html/manual/utilities.html
+++ b/libstdc++-v3/doc/html/manual/utilities.html
@@ -11,6 +11,6 @@
get slightly the wrong idea. In the interest of not reinventing
the wheel, we will refer you to the introduction to the functor
concept written by SGI as part of their STL, in
- their
- https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/functors.html.
+ their
+ https://web.archive.org/web/20171209002754/http://www.sgi.com/tech/stl/functors.html.