aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/gimple-array-bounds.cc24
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-17.C15
2 files changed, 31 insertions, 8 deletions
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index 2576556..d7fd2c7 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -372,12 +372,23 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
return warned;
}
-/* Hack around the internal representation constraints and build a zero
- element array type that actually renders as T[0] in diagnostcs. */
+/* Wrapper around build_array_type_nelts that makes sure the array
+ can be created at all and handles zero sized arrays specially. */
static tree
-build_zero_elt_array_type (tree eltype)
+build_printable_array_type (tree eltype, unsigned HOST_WIDE_INT nelts)
{
+ if (TYPE_SIZE_UNIT (eltype)
+ && TREE_CODE (TYPE_SIZE_UNIT (eltype)) == INTEGER_CST
+ && !integer_zerop (TYPE_SIZE_UNIT (eltype))
+ && TYPE_ALIGN_UNIT (eltype) > 1
+ && wi::zext (wi::to_wide (TYPE_SIZE_UNIT (eltype)),
+ ffs_hwi (TYPE_ALIGN_UNIT (eltype)) - 1) != 0)
+ eltype = TYPE_MAIN_VARIANT (eltype);
+
+ if (nelts)
+ return build_array_type_nelts (eltype, nelts);
+
tree idxtype = build_range_type (sizetype, size_zero_node, NULL_TREE);
tree arrtype = build_array_type (eltype, idxtype);
arrtype = build_distinct_type_copy (TYPE_MAIN_VARIANT (arrtype));
@@ -561,10 +572,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
return false;
offset_int nelts = arrbounds[1] / eltsize;
- if (nelts == 0)
- reftype = build_zero_elt_array_type (reftype);
- else
- reftype = build_array_type_nelts (reftype, nelts.to_uhwi ());
+ reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
}
else if (TREE_CODE (arg) == ADDR_EXPR)
{
@@ -675,7 +683,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
/* Treat a reference to a non-array object as one to an array
of a single element. */
if (TREE_CODE (reftype) != ARRAY_TYPE)
- reftype = build_array_type_nelts (reftype, 1);
+ reftype = build_printable_array_type (reftype, 1);
/* Extract the element type out of MEM_REF and use its size
to compute the index to print in the diagnostic; arrays
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C
new file mode 100644
index 0000000..64fbd08
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C
@@ -0,0 +1,15 @@
+// PR middle-end/99109
+// { dg-do compile }
+// { dg-options "-O2 -Warray-bounds" }
+
+typedef int A __attribute__((aligned (64)));
+void foo (int *);
+
+void
+bar (void)
+{
+ A b; // { dg-message "while referencing" }
+ int *p = &b;
+ int *x = (p - 1); // { dg-warning "outside array bounds" }
+ foo (x);
+}