tree-object-size: Always set computed bit for bdos [PR113012]
It is always safe to set the computed bit for dynamic object sizes at the end of collect_object_sizes_for because even in case of a dependency loop encountered in nested calls, we have an SSA temporary to actually finish the object size expression. The reexamine pass for dynamic object sizes is only for propagation of unknowns and gimplification of the size expressions, not for loop resolution as in the case of static object sizes. gcc/ChangeLog: PR tree-optimization/113012 * tree-object-size.cc (compute_builtin_object_size): Expand comment for dynamic object sizes. (collect_object_sizes_for): Always set COMPUTED bitmap for dynamic object sizes. gcc/testsuite/ChangeLog: PR tree-optimization/113012 * gcc.dg/ubsan/pr113012.c: New test case. Signed-off-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
This commit is contained in:
parent
fa1158c50a
commit
576c1fc440
2 changed files with 29 additions and 5 deletions
17
gcc/testsuite/gcc.dg/ubsan/pr113012.c
Normal file
17
gcc/testsuite/gcc.dg/ubsan/pr113012.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-fsanitize=undefined" } */
|
||||
|
||||
int *
|
||||
foo (int x, int y, int z, int w)
|
||||
{
|
||||
int *p = __builtin_malloc (z * sizeof (int));
|
||||
int *q = p - 1;
|
||||
while (--x > 0)
|
||||
{
|
||||
if (w + 1 > y)
|
||||
q = p - 1;
|
||||
++*q;
|
||||
++q;
|
||||
}
|
||||
return p;
|
||||
}
|
|
@ -1197,10 +1197,12 @@ compute_builtin_object_size (tree ptr, int object_size_type,
|
|||
osi.tos = NULL;
|
||||
}
|
||||
|
||||
/* First pass: walk UD chains, compute object sizes that
|
||||
can be computed. osi.reexamine bitmap at the end will
|
||||
contain what variables were found in dependency cycles
|
||||
and therefore need to be reexamined. */
|
||||
/* First pass: walk UD chains, compute object sizes that can be computed.
|
||||
osi.reexamine bitmap at the end will contain versions of SSA_NAMES
|
||||
that need to be reexamined. For both static and dynamic size
|
||||
computation, reexamination is for propagation across dependency loops.
|
||||
The dynamic case has the additional use case where the computed
|
||||
expression needs to be gimplified. */
|
||||
osi.pass = 0;
|
||||
osi.changed = false;
|
||||
collect_object_sizes_for (&osi, ptr);
|
||||
|
@ -1835,11 +1837,16 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
|
|||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (! reexamine || object_sizes_unknown_p (object_size_type, varno))
|
||||
/* Dynamic sizes use placeholder temps to return an answer, so it is always
|
||||
safe to set COMPUTED for them. */
|
||||
if ((object_size_type & OST_DYNAMIC)
|
||||
|| !reexamine || object_sizes_unknown_p (object_size_type, varno))
|
||||
{
|
||||
bitmap_set_bit (computed[object_size_type], varno);
|
||||
if (!(object_size_type & OST_DYNAMIC))
|
||||
bitmap_clear_bit (osi->reexamine, varno);
|
||||
else if (reexamine)
|
||||
bitmap_set_bit (osi->reexamine, varno);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue