Correct -Warray-bounds handling if function pointers [PR101601].
Resolves: PR middle-end/101601 - -Warray-bounds triggers error: arrays of functions are not meaningful PR middle-end/101601 gcc/ChangeLog: * gimple-array-bounds.cc (array_bounds_checker::check_mem_ref): Remove a pointless test. Handle pointers to functions. gcc/testsuite/ChangeLog: * g++.dg/warn/Warray-bounds-25.C: New test. * gcc.dg/Warray-bounds-85.c: New test.
This commit is contained in:
parent
2a837de28e
commit
b9cbf8c9e0
3 changed files with 111 additions and 15 deletions
|
@ -421,10 +421,9 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
/* The type and size of the access. */
|
||||
tree axstype = TREE_TYPE (ref);
|
||||
offset_int axssize = 0;
|
||||
if (TREE_CODE (axstype) != UNION_TYPE)
|
||||
if (tree access_size = TYPE_SIZE_UNIT (axstype))
|
||||
if (TREE_CODE (access_size) == INTEGER_CST)
|
||||
axssize = wi::to_offset (access_size);
|
||||
if (tree access_size = TYPE_SIZE_UNIT (axstype))
|
||||
if (TREE_CODE (access_size) == INTEGER_CST)
|
||||
axssize = wi::to_offset (access_size);
|
||||
|
||||
access_ref aref;
|
||||
if (!compute_objsize (ref, 0, &aref, ranges))
|
||||
|
@ -451,20 +450,28 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
tree reftype = TREE_TYPE (aref.ref);
|
||||
/* The size of the referenced array element. */
|
||||
offset_int eltsize = 1;
|
||||
/* The byte size of the array has already been determined above
|
||||
based on a pointer ARG. Set ELTSIZE to the size of the type
|
||||
it points to and REFTYPE to the array with the size, rounded
|
||||
down as necessary. */
|
||||
if (POINTER_TYPE_P (reftype))
|
||||
reftype = TREE_TYPE (reftype);
|
||||
if (TREE_CODE (reftype) == ARRAY_TYPE)
|
||||
reftype = TREE_TYPE (reftype);
|
||||
if (tree refsize = TYPE_SIZE_UNIT (reftype))
|
||||
if (TREE_CODE (refsize) == INTEGER_CST)
|
||||
eltsize = wi::to_offset (refsize);
|
||||
|
||||
const offset_int nelts = aref.sizrng[1] / eltsize;
|
||||
reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
|
||||
if (TREE_CODE (reftype) == FUNCTION_TYPE)
|
||||
/* Restore the original (pointer) type and avoid trying to create
|
||||
an array of functions (done below). */
|
||||
reftype = TREE_TYPE (aref.ref);
|
||||
else
|
||||
{
|
||||
/* The byte size of the array has already been determined above
|
||||
based on a pointer ARG. Set ELTSIZE to the size of the type
|
||||
it points to and REFTYPE to the array with the size, rounded
|
||||
down as necessary. */
|
||||
if (TREE_CODE (reftype) == ARRAY_TYPE)
|
||||
reftype = TREE_TYPE (reftype);
|
||||
if (tree refsize = TYPE_SIZE_UNIT (reftype))
|
||||
if (TREE_CODE (refsize) == INTEGER_CST)
|
||||
eltsize = wi::to_offset (refsize);
|
||||
|
||||
const offset_int nelts = aref.sizrng[1] / eltsize;
|
||||
reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
|
||||
}
|
||||
|
||||
/* Compute the more permissive upper bound when IGNORE_OFF_BY_ONE
|
||||
is set (when taking the address of the one-past-last element
|
||||
|
|
59
gcc/testsuite/g++.dg/warn/Warray-bounds-25.C
Normal file
59
gcc/testsuite/g++.dg/warn/Warray-bounds-25.C
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* PR middle-end/101601 - [12 Regression] -Warray-bounds triggers error:
|
||||
arrays of functions are not meaningful
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
|
||||
typedef void Fvv (void);
|
||||
|
||||
extern Fvv* pf; // { dg-message "'pf'" }
|
||||
|
||||
void f (...);
|
||||
|
||||
void test_funptr (void)
|
||||
{
|
||||
f (&pf);
|
||||
f (&pf + 1);
|
||||
f (&pf + 2); // { dg-warning "subscript 2 is outside array bounds of 'void \\\(\\\* ?\\\[1]\\\)\\\(\\\)'" }
|
||||
}
|
||||
|
||||
typedef int Fii_ (int, ...);
|
||||
|
||||
extern Fii_* pfa[3]; // { dg-message "'pfa'" }
|
||||
|
||||
void test_funptr_array (void)
|
||||
{
|
||||
f (pfa);
|
||||
f (pfa + 1);
|
||||
f (pfa + 2);
|
||||
f (pfa + 3);
|
||||
f (pfa + 4); // { dg-warning "subscript 4 is outside array bounds of 'int \\\(\\\* ?\\\[3]\\\)\\\(int, ...\\\)'" }
|
||||
}
|
||||
|
||||
|
||||
struct A;
|
||||
typedef void (A::*MFvv)(void);
|
||||
|
||||
MFvv pmf;
|
||||
|
||||
void test_memfunptr (void)
|
||||
{
|
||||
f (&pmf);
|
||||
f (&pmf + 1);
|
||||
f (&pmf + 2); // { dg-warning "subscript 2 is outside array bounds of 'void \\\(A::\\\* ?\\\[1]\\\)\\\(\\\)'" }
|
||||
}
|
||||
|
||||
|
||||
typedef int (A::*MFii)(int);
|
||||
|
||||
MFii pmfa[4];
|
||||
|
||||
void test_memfunptr_array (void)
|
||||
{
|
||||
f (pmfa);
|
||||
f (pmfa + 1);
|
||||
f (pmfa + 2);
|
||||
f (pmfa + 3);
|
||||
f (pmfa + 4);
|
||||
f (pmfa + 5); // { dg-warning "subscript 5 is outside array bounds of 'int \\\(A::\\\* ?\\\[4]\\\)\\\(int\\\)'" }
|
||||
|
||||
}
|
30
gcc/testsuite/gcc.dg/Warray-bounds-85.c
Normal file
30
gcc/testsuite/gcc.dg/Warray-bounds-85.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* PR middle-end/101601 - [12 Regression] -Warray-bounds triggers error:
|
||||
arrays of functions are not meaningful
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
|
||||
typedef void Fvv (void);
|
||||
|
||||
extern Fvv* pf; // { dg-message "'pf'" }
|
||||
|
||||
void f (void*);
|
||||
|
||||
void test_funptr (void)
|
||||
{
|
||||
f (&pf);
|
||||
f (&pf + 1);
|
||||
f (&pf + 2); // { dg-warning "subscript 2 is outside array bounds of 'void \\\(\\\*\\\[1]\\\)\\\(void\\\)'" }
|
||||
}
|
||||
|
||||
typedef int Fii_ (int, ...);
|
||||
|
||||
extern Fii_* pfa[3]; // { dg-message "'pfa'" }
|
||||
|
||||
void test_funptr_array (void)
|
||||
{
|
||||
f (pfa);
|
||||
f (pfa + 1);
|
||||
f (pfa + 2);
|
||||
f (pfa + 3);
|
||||
f (pfa + 4); // { dg-warning "subscript 4 is outside array bounds of 'int \\\(\\\*\\\[3]\\\)\\\(int, ...\\\)'" }
|
||||
}
|
Loading…
Add table
Reference in a new issue