diff options
author | Martin Sebor <msebor@redhat.com> | 2021-07-28 16:14:38 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2021-07-28 16:14:38 -0600 |
commit | b9cbf8c9e0bc72f59b643165247fae646560aadd (patch) | |
tree | ba826defe0728c66693746d587fa5e933ffc928e /gcc | |
parent | 2a837de28ee94b4ec201059a9a7aaa852e6808da (diff) | |
download | gcc-b9cbf8c9e0bc72f59b643165247fae646560aadd.zip gcc-b9cbf8c9e0bc72f59b643165247fae646560aadd.tar.gz gcc-b9cbf8c9e0bc72f59b643165247fae646560aadd.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-array-bounds.cc | 37 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Warray-bounds-25.C | 59 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Warray-bounds-85.c | 30 |
3 files changed, 111 insertions, 15 deletions
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index 3a5c2dd..0517e5d 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -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 diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-25.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-25.C new file mode 100644 index 0000000..a93da03 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-25.C @@ -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\\\)'" } + +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-85.c b/gcc/testsuite/gcc.dg/Warray-bounds-85.c new file mode 100644 index 0000000..0ee7120 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-85.c @@ -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, ...\\\)'" } +} |