PR middle-end/101601 - [12 Regression] -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.
@@ -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
new file mode 100644
@@ -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\\\)'" }
+
+}
new file mode 100644
@@ -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, ...\\\)'" }
+}