From 82cefc4898d4ccabe76e28d6626b91ca9e998923 Mon Sep 17 00:00:00 2001 From: Linsen Zhou Date: Fri, 17 Oct 2025 11:05:04 +0800 Subject: [PATCH] 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 --- gcc/testsuite/gcc.dg/torture/pr122012.c | 18 ++++++++++++++++++ gcc/tree-object-size.cc | 7 +++---- 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr122012.c 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 + +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 8545eff61a3e..65bcdd573250 100644 --- a/gcc/tree-object-size.cc +++ b/gcc/tree-object-size.cc @@ -2145,12 +2145,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;