On Wed, Feb 17, 2021 at 02:38:04PM -0700, Martin Sebor via Gcc-patches wrote:
> How does build_printable_array_type sound?

This adjusted version also works and has been successfully
bootstrapped/regtested on x86_64-linux and i686-linux.

Ok for trunk?

2021-02-18  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/99109
        * gimple-array-bounds.cc (build_zero_elt_array_type): Rename to ...
        (build_printable_array_type): ... this.  Add nelts argument.  For
        overaligned eltype, use TYPE_MAIN_VARIANT (eltype) instead.  If
        nelts, call build_array_type_nelts.
        (array_bounds_checker::check_mem_ref): Use build_printable_array_type
        instead of build_zero_elt_array_type and build_array_type_nelts.

        * g++.dg/warn/Warray-bounds-17.C: New test.

--- gcc/gimple-array-bounds.cc.jj       2021-01-04 10:25:37.471249246 +0100
+++ gcc/gimple-array-bounds.cc  2021-02-17 23:30:34.168721374 +0100
@@ -372,12 +372,23 @@ array_bounds_checker::check_array_ref (l
   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 (loc
        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 (loc
       /* 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
--- gcc/testsuite/g++.dg/warn/Warray-bounds-17.C.jj     2021-02-16 
17:24:14.178813304 +0100
+++ gcc/testsuite/g++.dg/warn/Warray-bounds-17.C        2021-02-16 
17:23:35.305251062 +0100
@@ -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);
+}


        Jakub

Reply via email to