diff options
author | Martin Sebor <msebor@redhat.com> | 2019-11-05 17:05:33 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-11-05 10:05:33 -0700 |
commit | 8299dfae9364468096a8005c4b3a83d4fa0f6e42 (patch) | |
tree | 91b38228622227e0e765dfeb1f81e4a365f3ae48 | |
parent | 3fd4f9242d9b7d2032126dc4851b4fdf5628dc35 (diff) | |
download | gcc-8299dfae9364468096a8005c4b3a83d4fa0f6e42.zip gcc-8299dfae9364468096a8005c4b3a83d4fa0f6e42.tar.gz gcc-8299dfae9364468096a8005c4b3a83d4fa0f6e42.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Warray-bounds-51.c | 61 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 20 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 35 |
5 files changed, 122 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 436939f..f3deffc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-11-05 Martin Sebor <msebor@redhat.com> + + 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 <aldyh@redhat.com> * tree-vrp.c (value_range::value_range): Fix whitespace. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37c4469..4932615 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-11-05 Martin Sebor <msebor@redhat.com> + + PR middle-end/92333 + PR middle-end/82608 + * gcc.dg/Warray-bounds-51.c: New test. + 2019-11-05 Nathan Sidwell <nathan@acm.org> 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 0000000..6028b11 --- /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 a8d0738..567aef8 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 64fb76b..9889095 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) |