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