tree-optimization/109609 - correctly interpret arg size in fnspec
By majority vote and a hint from the API name which is arg_max_access_size_given_by_arg_p this interprets a memory access size specified as given as other argument such as for strncpy in the testcase which has "1cO313" as specifying the _maximum_ size read/written rather than the exact size. There are two uses interpreting it that way already and one differing. The following adjusts the differing and clarifies the documentation. PR tree-optimization/109609 * attr-fnspec.h (arg_max_access_size_given_by_arg_p): Clarify semantics. * tree-ssa-alias.cc (check_fnspec): Correctly interpret the size given by arg_max_access_size_given_by_arg_p as maximum, not exact, size. * gcc.dg/torture/pr109609.c: New testcase.
This commit is contained in:
parent
1c101fcfaa
commit
e8d0035301
3 changed files with 43 additions and 5 deletions
|
@ -54,7 +54,7 @@
|
|||
' ' nothing is known
|
||||
't' the size of value written/read corresponds to the size of
|
||||
of the pointed-to type of the argument type
|
||||
'1'...'9' specifies the size of value written/read is given by the
|
||||
'1'...'9' specifies the size of value written/read is bound by the
|
||||
specified argument
|
||||
*/
|
||||
|
||||
|
@ -169,7 +169,7 @@ public:
|
|||
&& str[idx] != 'x' && str[idx] != 'X';
|
||||
}
|
||||
|
||||
/* Return true if load of memory pointed to by argument I is specified
|
||||
/* Return true if load of memory pointed to by argument I is bound
|
||||
by another argument. In this case set ARG. */
|
||||
bool
|
||||
arg_max_access_size_given_by_arg_p (unsigned int i, unsigned int *arg)
|
||||
|
|
26
gcc/testsuite/gcc.dg/torture/pr109609.c
Normal file
26
gcc/testsuite/gcc.dg/torture/pr109609.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
#define N 23
|
||||
#define MAX_LEN 13
|
||||
char dst[N + 1];
|
||||
|
||||
void __attribute__((noipa))
|
||||
invert(const char *id)
|
||||
{
|
||||
char buf[MAX_LEN];
|
||||
char *ptr = buf + sizeof(buf); // start from the end of buf
|
||||
*(--ptr) = '\0'; // terminate string
|
||||
while (*id && ptr > buf) {
|
||||
*(--ptr) = *(id++); // copy id backwards
|
||||
}
|
||||
__builtin_strncpy(dst, ptr, N); // copy ptr/buf to dst
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
invert("abcde");
|
||||
if (__builtin_strcmp(dst, "edcba"))
|
||||
__builtin_abort();
|
||||
return 0;
|
||||
}
|
|
@ -2726,9 +2726,21 @@ check_fnspec (gcall *call, ao_ref *ref, bool clobber)
|
|||
t = TREE_CHAIN (t);
|
||||
size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_VALUE (t)));
|
||||
}
|
||||
ao_ref_init_from_ptr_and_size (&dref,
|
||||
gimple_call_arg (call, i),
|
||||
size);
|
||||
poly_int64 size_hwi;
|
||||
if (size
|
||||
&& poly_int_tree_p (size, &size_hwi)
|
||||
&& coeffs_in_range_p (size_hwi, 0,
|
||||
HOST_WIDE_INT_MAX / BITS_PER_UNIT))
|
||||
{
|
||||
size_hwi = size_hwi * BITS_PER_UNIT;
|
||||
ao_ref_init_from_ptr_and_range (&dref,
|
||||
gimple_call_arg (call, i),
|
||||
true, 0, -1, size_hwi);
|
||||
}
|
||||
else
|
||||
ao_ref_init_from_ptr_and_range (&dref,
|
||||
gimple_call_arg (call, i),
|
||||
false, 0, -1, -1);
|
||||
if (refs_may_alias_p_1 (&dref, ref, false))
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue