]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-object-size: Fall back to wholesize for non-const offset
authorSiddhesh Poyarekar <siddhesh@gotplt.org>
Thu, 19 Sep 2024 02:36:09 +0000 (22:36 -0400)
committerSiddhesh Poyarekar <siddhesh@gotplt.org>
Thu, 17 Oct 2024 15:04:10 +0000 (11:04 -0400)
Don't bail out early if the offset to a pointer in __builtin_object_size
is a variable, return the wholesize instead since that is a better
fallback for maximum estimate.  This should keep checks in place for
fortified functions to constrain overflows to at lesat some extent.

gcc/ChangeLog:

PR middle-end/77608
* tree-object-size.cc (plus_stmt_object_size): Drop check for
constant offset.

gcc/testsuite/ChangeLog:

* gcc.dg/builtin-object-size-1.c (test12): New test.
(main): Call it.

Signed-off-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
gcc/testsuite/gcc.dg/builtin-object-size-1.c
gcc/tree-object-size.cc

index d6d13c5ef7a29efb0cd454621192f96c1d30dee3..6161adbd12890687da5c27f2c08d00ad16535172 100644 (file)
@@ -712,6 +712,25 @@ test11 (void)
 }
 #endif
 
+void
+__attribute__ ((noinline))
+test12 (unsigned off)
+{
+  char *buf2 = malloc (10);
+  char *p;
+  size_t t;
+
+  p = &buf2[off];
+
+#ifdef __builtin_object_size
+  if (__builtin_object_size (p, 0) != 10 - off)
+    FAIL ();
+#else
+  if (__builtin_object_size (p, 0) != 10)
+    FAIL ();
+#endif
+}
+
 int
 main (void)
 {
@@ -730,5 +749,7 @@ main (void)
 #ifndef SKIP_STRNDUP
   test11 ();
 #endif
+  test12 (0);
+  test12 (2);
   DONE ();
 }
index 78faae7ad0d34b16c01fcba88e87c4a2607fdcdd..0e4bf84fd11c10d4000fd1b51b13eb10cbc29c87 100644 (file)
@@ -1501,8 +1501,7 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple *stmt)
     return false;
 
   /* Handle PTR + OFFSET here.  */
-  if (size_valid_p (op1, object_size_type)
-      && (TREE_CODE (op0) == SSA_NAME || TREE_CODE (op0) == ADDR_EXPR))
+  if ((TREE_CODE (op0) == SSA_NAME || TREE_CODE (op0) == ADDR_EXPR))
     {
       if (TREE_CODE (op0) == SSA_NAME)
        {
@@ -1528,7 +1527,8 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple *stmt)
        ;
       else if ((object_size_type & OST_DYNAMIC)
               || bytes != wholesize
-              || compare_tree_int (op1, offset_limit) <= 0)
+              || (size_valid_p (op1, object_size_type)
+                  && compare_tree_int (op1, offset_limit) <= 0))
        bytes = size_for_offset (bytes, op1, wholesize);
       /* In the static case, with a negative offset, the best estimate for
         minimum size is size_unknown but for maximum size, the wholesize is a