tree-optimization/103961: Never compute offset for -1 size
Never try to compute size for offset when the object size is -1, which is either unknown maximum or uninitialized minimum irrespective of the osi->pass number. gcc/ChangeLog: PR tree-optimization/103961 * tree-object-size.c (plus_stmt_object_size): Always avoid computing offset for -1 size. gcc/testsuite/ChangeLog: PR tree-optimization/103961 * gcc.dg/pr103961.c: New test case. Co-authored-by: Jakub Jelinek <jakub@redhat.com> Signed-off-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
This commit is contained in:
parent
71b7213201
commit
026d44cbbd
30
gcc/testsuite/gcc.dg/pr103961.c
Normal file
30
gcc/testsuite/gcc.dg/pr103961.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void abort ();
|
||||
|
||||
extern inline __attribute__ ((__gnu_inline__)) int
|
||||
sprintf (char *restrict s, const char *restrict fmt, ...)
|
||||
{
|
||||
return __builtin___sprintf_chk (s, 1, __builtin_object_size (s, 1),
|
||||
fmt, __builtin_va_arg_pack ());
|
||||
}
|
||||
|
||||
void
|
||||
cap_to_text (int c)
|
||||
{
|
||||
char buf[1572];
|
||||
char *p;
|
||||
int n, t;
|
||||
p = 20 + buf;
|
||||
for (t = 8; t--; )
|
||||
{
|
||||
for (n = 0; n < c; n++)
|
||||
p += sprintf (p, "a,");
|
||||
p--;
|
||||
if (__builtin_object_size (p, 1) == 0)
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "abort" } } */
|
@ -990,13 +990,10 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple *stmt)
|
||||
addr_object_size (osi, op0, object_size_type, &bytes, &wholesize);
|
||||
}
|
||||
|
||||
/* In the first pass, do not compute size for offset if either the
|
||||
maximum size is unknown or the minimum size is not initialized yet;
|
||||
the latter indicates a dependency loop and will be resolved in
|
||||
subsequent passes. We attempt to compute offset for 0 minimum size
|
||||
too because a negative offset could be within bounds of WHOLESIZE,
|
||||
giving a non-zero result for VAR. */
|
||||
if (osi->pass != 0 || !size_unknown_p (bytes, 0))
|
||||
/* 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))
|
||||
bytes = size_for_offset (bytes, op1, wholesize);
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user