+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.
+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
--- /dev/null
+/* 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);
+}
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);
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;
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). */
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);
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)