From: Martin Sebor Date: Tue, 5 Nov 2019 17:05:33 +0000 (+0000) Subject: PR middle-end/92333 - missing variable name referencing VLA in warnings X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8299dfae9364468096a8005c4b3a83d4fa0f6e42;p=gcc.git PR middle-end/92333 - missing variable name referencing VLA in warnings PR middle-end/92333 - missing variable name referencing VLA in warnings PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index gcc/testsuite/ChangeLog: PR middle-end/92333 PR middle-end/82608 * gcc.dg/Warray-bounds-51.c: New test. gcc/ChangeLog: PR middle-end/92333 PR middle-end/82608 * tree-vrp.c (vrp_prop::check_array_ref): Handle VLAs with constant size. * tree-ssa-ccp.c (fold_builtin_alloca_with_align): Use a meaninful name and location for a temporary variable. From-SVN: r277854 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 436939fd990..f3deffc701f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-11-05 Martin Sebor + + PR middle-end/92333 + PR middle-end/82608 + * tree-vrp.c (vrp_prop::check_array_ref): Handle VLAs with constant + size. + * tree-ssa-ccp.c (fold_builtin_alloca_with_align): Use a meaninful + name and location for a temporary variable. + 2019-11-05 Aldy Hernandez * tree-vrp.c (value_range::value_range): Fix whitespace. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37c446913c2..4932615040b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-11-05 Martin Sebor + + PR middle-end/92333 + PR middle-end/82608 + * gcc.dg/Warray-bounds-51.c: New test. + 2019-11-05 Nathan Sidwell PR c++/92370 diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c b/gcc/testsuite/gcc.dg/Warray-bounds-51.c new file mode 100644 index 00000000000..6028b11637c --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c @@ -0,0 +1,61 @@ +/* PR middle-end/92333 - missing variable name referencing VLA in warnings + PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void sink (void*); + +void test_char_vla_location (void) +{ + unsigned nelts = 7; + + char vla[nelts]; // { dg-message "declared here|while referencing" } + + vla[0] = __LINE__; + vla[nelts] = 0; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla); +} + +void test_int_vla_location (void) +{ + unsigned nelts = 7; + + int vla[nelts]; // { dg-message "declared here|while referencing" } + + vla[0] = __LINE__; + vla[nelts] = 1; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla); +} + +void test_struct_char_vla_location (void) +{ + unsigned nelts = 7; + + struct { + char cvla[nelts]; // { dg-message "declared here|while referencing" } + } s; + + s.cvla[0] = __LINE__; + s.cvla[nelts - 1] = 0; + s.cvla[nelts] = 0; // { dg-warning "\\\[-Warray-bounds" } + + sink (&s); +} + + +void test_struct_int_vla_location (void) +{ + unsigned nelts = 7; + + struct { + int ivla[nelts]; // { dg-message "declared here|while referencing" } + } s; + + s.ivla[0] = __LINE__; + s.ivla[nelts - 1] = 0; + s.ivla[nelts] = 0; // { dg-warning "\\\[-Warray-bounds" } + + sink (&s); +} diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index a8d0738fbb0..567aef8bc26 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2222,7 +2222,25 @@ fold_builtin_alloca_with_align (gimple *stmt) elem_type = build_nonstandard_integer_type (BITS_PER_UNIT, 1); n_elem = size * 8 / BITS_PER_UNIT; array_type = build_array_type_nelts (elem_type, n_elem); - var = create_tmp_var (array_type); + + if (tree ssa_name = SSA_NAME_IDENTIFIER (lhs)) + { + /* Give the temporary a name derived from the name of the VLA + declaration so it can be referenced in diagnostics. */ + const char *name = IDENTIFIER_POINTER (ssa_name); + var = create_tmp_var (array_type, name); + } + else + var = create_tmp_var (array_type); + + if (gimple *lhsdef = SSA_NAME_DEF_STMT (lhs)) + { + /* Set the temporary's location to that of the VLA declaration + so it can be pointed to in diagnostics. */ + location_t loc = gimple_location (lhsdef); + DECL_SOURCE_LOCATION (var) = loc; + } + SET_DECL_ALIGN (var, TREE_INT_CST_LOW (gimple_call_arg (stmt, 1))); if (uid != 0) SET_DECL_PT_UID (var, uid); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 64fb76bda62..9889095fa13 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4085,6 +4085,9 @@ vrp_prop::check_array_ref (location_t location, tree ref, tree up_sub = low_sub; tree up_bound = array_ref_up_bound (ref); + /* Referenced decl if one can be determined. */ + tree decl = NULL_TREE; + /* Set for accesses to interior zero-length arrays. */ bool interior_zero_len = false; @@ -4115,7 +4118,8 @@ vrp_prop::check_array_ref (location_t location, tree ref, tree arg = TREE_OPERAND (ref, 0); poly_int64 off; - if (TREE_CODE (arg) == COMPONENT_REF) + const bool compref = TREE_CODE (arg) == COMPONENT_REF; + if (compref) { /* Try to determine the size of the trailing array from its initializer (if it has one). */ @@ -4124,12 +4128,27 @@ vrp_prop::check_array_ref (location_t location, tree ref, maxbound = refsize; } - if (maxbound == ptrdiff_max - && get_addr_base_and_unit_offset (arg, &off) - && known_gt (off, 0)) - maxbound = wide_int_to_tree (sizetype, - wi::sub (wi::to_wide (maxbound), - off)); + if (maxbound == ptrdiff_max) + { + /* Try to determine the size of the base object. Avoid + COMPONENT_REF already tried above. Using its DECL_SIZE + size wouldn't necessarily be correct if the reference is + to its flexible array member initialized in a different + translation unit. */ + tree base = get_addr_base_and_unit_offset (arg, &off); + if (!compref && base && DECL_P (base)) + if (tree basesize = DECL_SIZE_UNIT (base)) + if (TREE_CODE (basesize) == INTEGER_CST) + { + maxbound = basesize; + decl = base; + } + + if (known_gt (off, 0)) + maxbound = wide_int_to_tree (sizetype, + wi::sub (wi::to_wide (maxbound), + off)); + } else maxbound = fold_convert (sizetype, maxbound); @@ -4214,7 +4233,7 @@ vrp_prop::check_array_ref (location_t location, tree ref, fprintf (dump_file, "\n"); } - ref = TREE_OPERAND (ref, 0); + ref = decl ? decl : TREE_OPERAND (ref, 0); tree rec = NULL_TREE; if (TREE_CODE (ref) == COMPONENT_REF)