aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-object-size.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@gotplt.org>2022-01-14 08:56:15 +0530
committerSiddhesh Poyarekar <siddhesh@gotplt.org>2022-01-14 11:51:44 +0530
commit17df585a3a6a852c71883cc2ff40e111a6875149 (patch)
tree99894075fe2ee96d9f4bc047c4f994bdfd859a86 /gcc/tree-object-size.c
parentb77e3b4e4589e56c01511fabdbaadb029cd47f5c (diff)
downloadgcc-17df585a3a6a852c71883cc2ff40e111a6875149.zip
gcc-17df585a3a6a852c71883cc2ff40e111a6875149.tar.gz
gcc-17df585a3a6a852c71883cc2ff40e111a6875149.tar.bz2
tree-optimization/104009: Conservative underflow estimate in object size
Restrict negative offset computation only to dynamic object sizes, where size expressions are accurate and not a maximum/minimum estimate and in cases where negative offsets definitely mean an underflow, e.g. in MEM_REF of the whole object with negative ofset in addr_object_size. This ends up missing some cases where __builtin_object_size could have come up with more precise results, so tests have been adjusted to reflect that. gcc/ChangeLog: PR tree-optimization/104009 * tree-object-size.c (compute_builtin_object_size): Bail out on negative offset. (plus_stmt_object_size): Return maximum of wholesize and minimum of 0 for negative offset. gcc/testsuite/ChangeLog: PR tree-optimization/104009 * gcc.dg/builtin-object-size-1.c (test10): New test. * gcc.dg/builtin-object-size-3.c (test10): Likewise. (test9): Expect zero size for negative offsets. * gcc.dg/builtin-object-size-4.c (test8): Likewise. * gcc.dg/builtin-object-size-5.c (test7): Drop test for __builtin_object_size. Signed-off-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
Diffstat (limited to 'gcc/tree-object-size.c')
-rw-r--r--gcc/tree-object-size.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 3a39e6f..8be0df6 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -1054,7 +1054,8 @@ compute_builtin_object_size (tree ptr, int object_size_type,
ptr = gimple_assign_rhs1 (def);
if (((object_size_type & OST_DYNAMIC)
- || tree_fits_shwi_p (offset))
+ || (tree_fits_shwi_p (offset)
+ && compare_tree_int (offset, offset_limit) <= 0))
&& compute_builtin_object_size (ptr, object_size_type,
psize))
{
@@ -1346,8 +1347,18 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple *stmt)
/* size_for_offset doesn't make sense for -1 size, but it does for size 0
since the wholesize could be non-zero and a negative offset could give
a non-zero size. */
- if (!size_unknown_p (bytes, 0))
+ if (size_unknown_p (bytes, 0))
+ ;
+ else if ((object_size_type & OST_DYNAMIC)
+ || 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
+ better estimate than size_unknown. */
+ else if (object_size_type & OST_MINIMUM)
+ bytes = size_unknown (object_size_type);
+ else
+ bytes = wholesize;
}
else
bytes = wholesize = size_unknown (object_size_type);