From b9cbf8c9e0bc72f59b643165247fae646560aadd Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Jul 2021 16:14:38 -0600 Subject: 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. --- gcc/gimple-array-bounds.cc | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'gcc/gimple-array-bounds.cc') 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 -- cgit v1.1