diff --git a/SOURCES/gcc8-libstdc++-make_shared.patch b/SOURCES/gcc8-libstdc++-make_shared.patch new file mode 100644 index 0000000..59256d8 --- /dev/null +++ b/SOURCES/gcc8-libstdc++-make_shared.patch @@ -0,0 +1,61 @@ +commit 79fa567e234585dc6a71f9bd069101c993513f3e +Author: Jonathan Wakely +Date: Thu Apr 22 15:46:51 2021 +0100 + + libstdc++: Reject std::make_shared [PR 99006] + + Prior to C++20 it should be ill-formed to use std::make_shared with an + array type (and we don't support the C++20 feature to make it valid yet + anyway). + + libstdc++-v3/ChangeLog: + + PR libstdc++/99006 + * include/bits/shared_ptr.h (allocate_shared): Assert that _Tp + is not an array type. + * include/bits/shared_ptr_base.h (__allocate_shared): Likewise. + * testsuite/20_util/shared_ptr/creation/99006.cc: New test. + + (cherry picked from commit 55650236cd97d81f42f9fdb4f6bcb12babafe51f) + +diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h +index 281600b2901..4ddc52ae723 100644 +--- a/libstdc++-v3/include/bits/shared_ptr.h ++++ b/libstdc++-v3/include/bits/shared_ptr.h +@@ -698,6 +698,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + inline shared_ptr<_Tp> + allocate_shared(const _Alloc& __a, _Args&&... __args) + { ++ static_assert(!is_array<_Tp>::value, "make_shared not supported"); ++ + return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a}, + std::forward<_Args>(__args)...); + } +diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h +index 0367c2d51a5..8af6e9fb11c 100644 +--- a/libstdc++-v3/include/bits/shared_ptr_base.h ++++ b/libstdc++-v3/include/bits/shared_ptr_base.h +@@ -1822,6 +1822,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + inline __shared_ptr<_Tp, _Lp> + __allocate_shared(const _Alloc& __a, _Args&&... __args) + { ++ static_assert(!is_array<_Tp>::value, "make_shared not supported"); ++ + return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a}, + std::forward<_Args>(__args)...); + } +diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc +new file mode 100644 +index 00000000000..d5f7a5da5e9 +--- /dev/null ++++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc +@@ -0,0 +1,9 @@ ++// FIXME: This should use { target { ! c++20 } } ++// { dg-do compile } ++ ++#include ++ ++auto p = std::make_shared(2); // { dg-error "here" } ++auto q = std::make_shared(1, 2); // { dg-error "here" } ++ ++// { dg-prune-output "static assertion failed" } diff --git a/SOURCES/gcc8-pr105502.patch b/SOURCES/gcc8-pr105502.patch new file mode 100644 index 0000000..7200b9d --- /dev/null +++ b/SOURCES/gcc8-pr105502.patch @@ -0,0 +1,98 @@ +From b005000525ab0a5116d21217c41fb1da5bd03796 Mon Sep 17 00:00:00 2001 +From: Jonathan Wakely +Date: Fri, 6 May 2022 21:19:17 +0100 +Subject: [PATCH] libstdc++: Fix deserialization for std::normal_distribution + [PR105502] + +This fixes a regression in std::normal_distribution deserialization that +caused the object to be left unchanged if the __state_avail value read +from the stream was false. + +libstdc++-v3/ChangeLog: + + PR libstdc++/105502 + * include/bits/random.tcc + (operator>>(basic_istream&, normal_distribution&)): + Update state when __state_avail is false. + * testsuite/26_numerics/random/normal_distribution/operators/serialize.cc: + Check that deserialized object equals serialized one. + +(cherry picked from commit 909ef4e2727ddc50a32d6ad379a1f1ccc1043c6a) +--- + libstdc++-v3/include/bits/random.tcc | 2 +- + .../operators/serialize.cc | 36 ++++++++++++++++++- + 2 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc +index 0a299baedc5..0f758671f69 100644 +--- a/libstdc++-v3/include/bits/random.tcc ++++ b/libstdc++-v3/include/bits/random.tcc +@@ -1941,7 +1941,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + bool __saved_avail; + if (__is >> __mean >> __stddev >> __saved_avail) + { +- if (__saved_avail && (__is >> __x._M_saved)) ++ if (!__saved_avail || (__is >> __x._M_saved)) + { + __x._M_saved_available = __saved_avail; + __x.param(typename normal_distribution<_RealType>:: +diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc +index a65d4004161..8cc70886bc7 100644 +--- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc ++++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc +@@ -25,6 +25,7 @@ + + #include + #include ++#include + + void + test01() +@@ -37,10 +38,43 @@ test01() + str << u; + + str >> v; ++ VERIFY( u == v ); ++} ++ ++void ++test_pr105502() ++{ ++ // PR libstdc++/105502 std::normal_distribution deserialization issue ++ std::stringstream str; ++ std::normal_distribution<> d{1, 2}, d2; ++ std::minstd_rand0 g; ++ str << d; ++ VERIFY( str ); ++ str >> d2; ++ VERIFY( str ); ++ VERIFY( d == d2 ); ++ ++ (void) d(g); // sets d._M_saved_available = true ++ str.str(""); ++ str.clear(); ++ str << d; ++ VERIFY( str ); ++ str >> d2; ++ VERIFY( str ); ++ VERIFY( d == d2 ); ++ ++ (void) d(g); // sets d._M_saved_available = false ++ str.str(""); ++ str.clear(); ++ str << d; ++ VERIFY( str ); ++ str >> d2; ++ VERIFY( str ); ++ VERIFY( d == d2 ); + } + + int main() + { + test01(); +- return 0; ++ test_pr105502(); + } +-- +2.31.1 + diff --git a/SOURCES/gcc8-pr99536.patch b/SOURCES/gcc8-pr99536.patch new file mode 100644 index 0000000..db6706e --- /dev/null +++ b/SOURCES/gcc8-pr99536.patch @@ -0,0 +1,47 @@ +commit 29dad307b5d7cfdb6626c11c8e43ebff941c950b +Author: Jonathan Wakely +Date: Thu Mar 11 16:43:51 2021 +0000 + + libstdc++: Initialize std::normal_distribution::_M_saved [PR 99536] + + This avoids a false positive -Wmaybe-uninitialized warning, by + initializing _M_saved on construction. + + libstdc++-v3/ChangeLog: + + PR libstdc++/99536 + * include/bits/random.h (normal_distribution): Use + default-initializer for _M_saved and _M_saved_available. + + (cherry picked from commit 67e397660611990efd98f9e4106c1ee81f6803a4) + +diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h +index b36781ed290..3385345d273 100644 +--- a/libstdc++-v3/include/bits/random.h ++++ b/libstdc++-v3/include/bits/random.h +@@ -1974,12 +1974,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + explicit + normal_distribution(result_type __mean = result_type(0), + result_type __stddev = result_type(1)) +- : _M_param(__mean, __stddev), _M_saved_available(false) ++ : _M_param(__mean, __stddev) + { } + + explicit + normal_distribution(const param_type& __p) +- : _M_param(__p), _M_saved_available(false) ++ : _M_param(__p) + { } + + /** +@@ -2158,8 +2158,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + const param_type& __p); + + param_type _M_param; +- result_type _M_saved; +- bool _M_saved_available; ++ result_type _M_saved = 0; ++ bool _M_saved_available = false; + }; + + /** diff --git a/SOURCES/gcc8-rh2117838.patch b/SOURCES/gcc8-rh2117838.patch new file mode 100644 index 0000000..1b35e7d --- /dev/null +++ b/SOURCES/gcc8-rh2117838.patch @@ -0,0 +1,103 @@ +diff --git a/gcc/testsuite/g++.dg/torture/phi-1.C b/gcc/testsuite/g++.dg/torture/phi-1.C +new file mode 100644 +index 00000000000..69fb3d7ba38 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/torture/phi-1.C +@@ -0,0 +1,28 @@ ++// { dg-do compile { target c++11 } } ++// { dg-options "--param early-inlining-insns=14" } ++ ++struct Element; ++template struct __array_traits { typedef Element _Type[_Nm]; }; ++template struct array { ++ typename __array_traits<_Nm>::_Type _M_elems; ++}; ++bool logLevel(); ++struct LogCapture { ++ void stream(); ++}; ++struct Element { ++ Element(); ++ long data_; ++}; ++using ElementArray = array<6>; ++struct ElementManager { ++ ElementManager(); ++ ElementArray array_; ++}; ++static ElementArray makeArray() { ++ if (logLevel()) ++ LogCapture().stream(); ++ ElementArray foo; ++ return foo; ++} ++ElementManager::ElementManager() : array_(makeArray()) {} +diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c +index 84e58e66628..78c0c6a4189 100644 +--- a/gcc/tree-cfg.c ++++ b/gcc/tree-cfg.c +@@ -2944,35 +2944,6 @@ last_and_only_stmt (basic_block bb) + return NULL; + } + +-/* Reinstall those PHI arguments queued in OLD_EDGE to NEW_EDGE. */ +- +-static void +-reinstall_phi_args (edge new_edge, edge old_edge) +-{ +- edge_var_map *vm; +- int i; +- gphi_iterator phis; +- +- vec *v = redirect_edge_var_map_vector (old_edge); +- if (!v) +- return; +- +- for (i = 0, phis = gsi_start_phis (new_edge->dest); +- v->iterate (i, &vm) && !gsi_end_p (phis); +- i++, gsi_next (&phis)) +- { +- gphi *phi = phis.phi (); +- tree result = redirect_edge_var_map_result (vm); +- tree arg = redirect_edge_var_map_def (vm); +- +- gcc_assert (result == gimple_phi_result (phi)); +- +- add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm)); +- } +- +- redirect_edge_var_map_clear (old_edge); +-} +- + /* Returns the basic block after which the new basic block created + by splitting edge EDGE_IN should be placed. Tries to keep the new block + near its "logical" location. This is of most help to humans looking +@@ -3012,11 +2983,24 @@ gimple_split_edge (edge edge_in) + new_bb = create_empty_bb (after_bb); + new_bb->count = edge_in->count (); + +- e = redirect_edge_and_branch (edge_in, new_bb); +- gcc_assert (e == edge_in); +- ++ /* We want to avoid re-allocating PHIs when we first ++ add the fallthru edge from new_bb to dest but we also ++ want to avoid changing PHI argument order when ++ first redirecting edge_in away from dest. The former ++ avoids changing PHI argument order by adding them ++ last and then the redirection swapping it back into ++ place by means of unordered remove. ++ So hack around things by temporarily removing all PHIs ++ from the destination during the edge redirection and then ++ making sure the edges stay in order. */ ++ gimple_seq saved_phis = phi_nodes (dest); ++ unsigned old_dest_idx = edge_in->dest_idx; ++ set_phi_nodes (dest, NULL); + new_edge = make_single_succ_edge (new_bb, dest, EDGE_FALLTHRU); +- reinstall_phi_args (new_edge, e); ++ e = redirect_edge_and_branch (edge_in, new_bb); ++ gcc_assert (e == edge_in && new_edge->dest_idx == old_dest_idx); ++ /* set_phi_nodes sets the BB of the PHI nodes, so do it manually here. */ ++ dest->il.gimple.phi_nodes = saved_phis; + + return new_bb; + } diff --git a/SOURCES/gcc8-rh2137448.patch b/SOURCES/gcc8-rh2137448.patch new file mode 100644 index 0000000..8c74382 --- /dev/null +++ b/SOURCES/gcc8-rh2137448.patch @@ -0,0 +1,110 @@ +commit 8b89515caca5149329c0cd20485e69e2d0f879d4 +Author: Marek Polacek +Date: Wed Dec 7 13:44:38 2022 -0500 + + strlen: Use D_S_U in maybe_set_strlen_range + + This patch fixes #2137448 where the customer uses strlen on a buffer + that was filled by converting the buffer to a struct and copying a string + into a flexible array member of the struct. + + This regressed with r262438 in the sense that the strlen was folded to 0. + The strlen=0 result started with + https://gcc.gnu.org/pipermail/gcc-patches/2018-July/501912.html + https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=715fcd73b66c639d9e0e3f3ef9c6ff9d621d7131 + which seems like an undesirable change. It was fixed (back to strlen=3) by + https://gcc.gnu.org/legacy-ml/gcc-patches/2019-01/msg00069.html + https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=d4bf69750d31d08068f8242225b8fa06cdf11411 + but the changes are not backportable. + + Instead, this patch makes maybe_set_strlen_range use DECL_SIZE_UNIT + rather than TYPE_SIZE_UNIT, fixing the regression. + + I could never reproduce the problem in C, only C++. C/C++ represent array + type domains differently: C has + + char[0:] + + but C++ + + char[0:18446744073709551615] + + I'm not sure if that explains it. In any case, I put the new test into + c-c++-common/. + + Also, the original test had + + printf("strlen = %zu\n", strlen(q->name)); + + so naturally, for the testsuite, I wanted to convert that into + + if (strlen(q->name) != ...) + __builtin_abort (); + + but then I could no longer reproduce the problem. After some poking + I realized I want -fno-early-inlining. + + Co-authored-by: Jakub Jelinek + +diff --git a/gcc/testsuite/c-c++-common/torture/strlenopt-1.c b/gcc/testsuite/c-c++-common/torture/strlenopt-1.c +new file mode 100644 +index 00000000000..e8c11044119 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/torture/strlenopt-1.c +@@ -0,0 +1,38 @@ ++/* { dg-do run } */ ++/* { dg-options "-fno-early-inlining" } */ ++ ++#define FORTIFY_SOURCE 2 ++ ++struct S { ++ char skip; ++ char name[0]; ++}; ++ ++static char static_buf[4]; ++ ++static void ++print_name_len(void *p) ++{ ++ struct S *q = (struct S *) p; ++ if (__builtin_strlen(q->name) != 2) ++ __builtin_abort (); ++} ++ ++int ++main(void) ++{ ++ // treat static storage as struct ++ struct S *c = (struct S *)static_buf; ++ __builtin_strcpy(c->name, "aa"); ++ ++ // copy static storage to stack storage ++ char stack_buf[4] = { 0 }; ++ __builtin_memcpy(stack_buf, static_buf, 4); ++ ++ // static and stack both now contain ( 0, 'a', 'a', 0 } ++ ++ // indirectly pass the stack storage to the length function ++ char *s = (char *)stack_buf; ++ print_name_len(s); ++ return 0; ++} +diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c +index 55e82e7b638..da47046cc2a 100644 +--- a/gcc/tree-ssa-strlen.c ++++ b/gcc/tree-ssa-strlen.c +@@ -1200,8 +1200,11 @@ maybe_set_strlen_range (tree lhs, tree src) + || array_at_struct_end_p (src)) + return; + +- tree type = TREE_TYPE (src); +- if (tree size = TYPE_SIZE_UNIT (type)) ++ src = get_base_address (src); ++ if (!DECL_P (src)) ++ return; ++ ++ if (tree size = DECL_SIZE_UNIT (src)) + if (size && TREE_CODE (size) == INTEGER_CST) + { + wide_int max = wi::to_wide (size); diff --git a/SPECS/gcc.spec b/SPECS/gcc.spec index c87b4c9..71bdf33 100644 --- a/SPECS/gcc.spec +++ b/SPECS/gcc.spec @@ -4,7 +4,7 @@ %global gcc_major 8 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 15 +%global gcc_release 18 %global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f %global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24 %global _unpackaged_files_terminate_build 0 @@ -286,7 +286,7 @@ Patch25: gcc8-aarch64-mtune-neoverse-512tvb.patch Patch26: gcc8-rh2028609.patch Patch27: gcc8-libgfortran-default-values.patch Patch28: gcc8-rh2001788.patch - +Patch29: gcc8-rh2117838.patch Patch30: gcc8-rh1668903-1.patch Patch31: gcc8-rh1668903-2.patch Patch32: gcc8-rh1668903-3.patch @@ -294,6 +294,10 @@ Patch33: gcc8-harden-1.patch Patch34: gcc8-harden-2.patch Patch35: gcc8-harden-3.patch Patch36: gcc8-harden-4.patch +Patch37: gcc8-pr105502.patch +Patch38: gcc8-pr99536.patch +Patch39: gcc8-libstdc++-make_shared.patch +Patch40: gcc8-rh2137448.patch Patch1000: nvptx-tools-no-ptxas.patch Patch1001: nvptx-tools-build.patch @@ -896,6 +900,7 @@ so that there cannot be any synchronization problems. %patch26 -p1 -b .rh2028609~ %patch27 -p1 -b .libgfortran-default~ %patch28 -p1 -b .rh2001788~ +%patch29 -p1 -b .rh2117838~ %patch30 -p0 -b .rh1668903-1~ %patch31 -p0 -b .rh1668903-2~ @@ -904,6 +909,10 @@ so that there cannot be any synchronization problems. %patch34 -p1 -b .harden-2~ %patch35 -p1 -b .harden-3~ %patch36 -p1 -b .harden-4~ +%patch37 -p1 -b .pr105502~ +%patch38 -p1 -b .pr99536~ +%patch39 -p1 -b .make_shared~ +%patch40 -p1 -b .rh2137448~ cd nvptx-tools-%{nvptx_tools_gitrev} %patch1000 -p1 -b .nvptx-tools-no-ptxas~ @@ -3311,6 +3320,18 @@ fi %{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0.0.0 %changelog +* Tue Dec 6 2022 Marek Polacek 8.5.0-18 +- fix strlen range with a flexible member array (#2137448) + +* Mon Oct 3 2022 Marek Polacek 8.5.0-17 +- fix deserialization for std::normal_distribution (#2130392, + PR libstdc++/105502) +- initialize std::normal_distribution::_M_saved (PR libstdc++/99536) +- reject std::make_shared (PR libstdc++/99006) + +* Thu Sep 29 2022 Marek Polacek 8.5.0-16 +- avoid changing PHIs in GIMPLE split_edge (#2117838) + * Wed Jul 20 2022 Marek Polacek 8.5.0-15 - backport straight-line-speculation mitigation (#2108721)