This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] handle constant size VLAs in -Warray-bounds (PR 82608, 92333)


-Warray-bounds doesn't yet have the logic to detect out-of-bounds
indices into dynamically allocated arrays like VLAs because it
doesn't track allocation calls.  But the warning could detect
such errors in accesses to VLAs with constant sizes even without
such tracking.

The attached patch adds this capability.  Testing the warning
revealed that the names and locations of VLAs with constant sizes
are unavailable, making the warnings less useful than they could
be otherwise.  So the other part of the patch also arranges for
the arrays backing the constant size VLAs to have names that
reflect those of the VLAs, and the same location.

Tested on x86_64-linux.

Martin
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-53.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.

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 277806)
+++ gcc/tree-vrp.c	(working copy)
@@ -4154,6 +4154,9 @@ vrp_prop::check_array_ref (location_t location, tr
   low_sub = up_sub = TREE_OPERAND (ref, 1);
   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;
 
@@ -4182,7 +4185,8 @@ vrp_prop::check_array_ref (location_t location, tr
 	  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).  */
@@ -4191,12 +4195,27 @@ vrp_prop::check_array_ref (location_t location, tr
 		  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);
 
@@ -4281,7 +4300,7 @@ vrp_prop::check_array_ref (location_t location, tr
 	  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)
Index: gcc/tree-ssa-ccp.c
===================================================================
--- gcc/tree-ssa-ccp.c	(revision 277806)
+++ gcc/tree-ssa-ccp.c	(working copy)
@@ -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: gcc/testsuite/gcc.dg/Warray-bounds-53.c
===================================================================
--- gcc/testsuite/gcc.dg/Warray-bounds-53.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/Warray-bounds-53.c	(working copy)
@@ -0,0 +1,50 @@
+/* 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" }
+
+  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" }
+
+  vla[0] = __LINE__;
+  vla[nelts] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+
+  sink (vla);
+}
+
+void test_struct_vla_location (void)
+{
+  unsigned nelts = 7;
+
+  struct {
+    char cvla[nelts]; // { dg-message "declared here" }
+    int ivla[nelts];  // { dg-message "declared here" }
+  } s;
+
+  s.cvla[0] = __LINE__;
+  s.cvla[nelts - 1] = 0;
+  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
+
+  s.ivla[0] = __LINE__;
+  s.ivla[nelts - 1] = 0;
+  s.ivla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
+
+  sink (&s);
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]