From 21b7d08714c4964403848db4144003835ff5245a Mon Sep 17 00:00:00 2001
From: Linsen Zhou <i@lin.moe>
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 <i@lin.moe>
(cherry picked from commit 82cefc4898d4ccabe76e28d6626b91ca9e998923)
---
 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 00000000000..055915a1e98
--- /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 2d13ab79a84..76dc2446059 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;
-- 
2.51.0

