tree-object-size.cc: Fix assert constant offset in check_for_plus_in_loops [PR122012]

After commit 51b85dfeb1, 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 <i@lin.moe>
This commit is contained in:
Linsen Zhou 2025-10-17 11:05:04 +08:00 committed by Siddhesh Poyarekar
parent fa8ca9554d
commit 82cefc4898
2 changed files with 21 additions and 4 deletions

View File

@ -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);
}

View File

@ -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;