https://gcc.gnu.org/g:ff3e6f43c69ff3ef81daedb9fe7e69b9860b0b5a
commit r15-10444-gff3e6f43c69ff3ef81daedb9fe7e69b9860b0b5a Author: Linsen Zhou <[email protected]> Date: Fri Oct 17 11:05:04 2025 +0800 tree-object-size.cc: Fix assert constant offset in check_for_plus_in_loops [PR122012] After commit 51b85dfeb19652bf3e0aaec08828ba7cee1e641c, when the pointer offset is a variable in the loop, the object size of the pointer may also need to be reexamined. Which make gcc_assert in the check_for_plus_in_loops failed. gcc/ChangeLog: PR tree-optimization/122012 * tree-object-size.cc (check_for_plus_in_loops): Skip check for the variable offset gcc/testsuite/ChangeLog: PR tree-optimization/122012 * gcc.dg/torture/pr122012.c: New test. Signed-off-by: Linsen Zhou <[email protected]> (cherry picked from commit 82cefc4898d4ccabe76e28d6626b91ca9e998923) Diff: --- gcc/testsuite/gcc.dg/torture/pr122012.c | 18 ++++++++++++++++++ gcc/tree-object-size.cc | 7 +++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr122012.c b/gcc/testsuite/gcc.dg/torture/pr122012.c new file mode 100644 index 000000000000..055915a1e980 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr122012.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +#include <stdlib.h> + +void foo(); + +void test(size_t step) { + char *buf = malloc(64); + char *p = buf; + size_t i; + + for(i = 0; i < 64; ++i) { + p += 4; + if (__builtin_object_size (p, 2) != 0) + foo(); + p += step; + } + free(buf); +} diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc index 2d13ab79a84a..76dc24460597 100644 --- a/gcc/tree-object-size.cc +++ b/gcc/tree-object-size.cc @@ -2153,12 +2153,11 @@ check_for_plus_in_loops (struct object_size_info *osi, tree var) && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR) { tree basevar = gimple_assign_rhs1 (stmt); - tree cst = gimple_assign_rhs2 (stmt); - - gcc_assert (TREE_CODE (cst) == INTEGER_CST); + tree offset = gimple_assign_rhs2 (stmt); /* Skip non-positive offsets. */ - if (integer_zerop (cst) || compare_tree_int (cst, offset_limit) > 0) + if (TREE_CODE (offset) != INTEGER_CST + || integer_zerop (offset) || compare_tree_int (offset, offset_limit) > 0) return; osi->depths[SSA_NAME_VERSION (basevar)] = 1;
