PR middle-end/92333 - missing variable name referencing VLA in warnings
authorMartin Sebor <msebor@redhat.com>
Tue, 5 Nov 2019 17:05:33 +0000 (17:05 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 5 Nov 2019 17:05:33 +0000 (10:05 -0700)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Warray-bounds-51.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c
gcc/tree-vrp.c

index 436939f..f3deffc 100644 (file)
@@ -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.
index 37c4469..4932615 100644 (file)
@@ -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 (file)
index 0000000..6028b11
--- /dev/null
@@ -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);
+}
index a8d0738..567aef8 100644 (file)
@@ -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);
index 64fb76b..9889095 100644 (file)
@@ -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)