aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-array-bounds.cc
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-07-28 16:14:38 -0600
committerMartin Sebor <msebor@redhat.com>2021-07-28 16:14:38 -0600
commitb9cbf8c9e0bc72f59b643165247fae646560aadd (patch)
treeba826defe0728c66693746d587fa5e933ffc928e /gcc/gimple-array-bounds.cc
parent2a837de28ee94b4ec201059a9a7aaa852e6808da (diff)
downloadgcc-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/gimple-array-bounds.cc')
-rw-r--r--gcc/gimple-array-bounds.cc37
1 files changed, 22 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