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 3662021..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 17 +%global gcc_release 18 %global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f %global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24 %global _unpackaged_files_terminate_build 0 @@ -297,6 +297,7 @@ 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 @@ -911,6 +912,7 @@ so that there cannot be any synchronization problems. %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~ @@ -3318,6 +3320,9 @@ 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)