correct MEM_REF bounds checking of arrays (PR 91584)

Message ID 339ecf17-c049-9c45-4ea2-26153f804bf4@gmail.com
State New
Headers show
Series
  • correct MEM_REF bounds checking of arrays (PR 91584)
Related show

Commit Message

Martin Sebor Aug. 29, 2019, 10:36 p.m.
The -Warray-bounds enhancement I added to GCC 9 causes false
positives in languages like Fortran whose first array element
is at a non-zero index.  The attached patch has the function
responsible for the warning normalize the array bounds to
always start at zero to avoid these false positives.

Tested on x86_64-linux.

Martin

Comments

Richard Biener Aug. 30, 2019, 7:28 a.m. | #1
On Fri, Aug 30, 2019 at 12:36 AM Martin Sebor <msebor@gmail.com> wrote:
>

> The -Warray-bounds enhancement I added to GCC 9 causes false

> positives in languages like Fortran whose first array element

> is at a non-zero index.  The attached patch has the function

> responsible for the warning normalize the array bounds to

> always start at zero to avoid these false positives.

>

> Tested on x86_64-linux.


OK.

Thanks,
Richard.

> Martin

Patch

PR middle-end/91584 - Bogus warning from -Warray-bounds during string assignment

gcc/ChangeLog:

	PR middle-end/91584
	* tree-vrp.c (vrp_prop::check_mem_ref): Normalize type domain bounds
	before using them to validate MEM_REF offset.

gcc/testsuite/ChangeLog:
	* gfortran.dg/char_array_constructor_4.f90: New test.

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 275047)
+++ gcc/tree-vrp.c	(working copy)
@@ -4703,31 +4703,23 @@  vrp_prop::check_mem_ref (location_t location, tree
       || RECORD_OR_UNION_TYPE_P (reftype))
     return false;
 
+  arrbounds[0] = 0;
+
   offset_int eltsize;
   if (TREE_CODE (reftype) == ARRAY_TYPE)
     {
       eltsize = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (reftype)));
-
       if (tree dom = TYPE_DOMAIN (reftype))
 	{
 	  tree bnds[] = { TYPE_MIN_VALUE (dom), TYPE_MAX_VALUE (dom) };
-	  if (array_at_struct_end_p (arg)
-	      || !bnds[0] || !bnds[1])
-	    {
-	      arrbounds[0] = 0;
-	      arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize));
-	    }
+	  if (array_at_struct_end_p (arg) || !bnds[0] || !bnds[1])
+	    arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize));
 	  else
-	    {
-	      arrbounds[0] = wi::to_offset (bnds[0]) * eltsize;
-	      arrbounds[1] = (wi::to_offset (bnds[1]) + 1) * eltsize;
-	    }
+	    arrbounds[1] = (wi::to_offset (bnds[1]) - wi::to_offset (bnds[0])
+			    + 1) * eltsize;
 	}
       else
-	{
-	  arrbounds[0] = 0;
-	  arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize));
-	}
+	arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize));
 
       if (TREE_CODE (ref) == MEM_REF)
 	{
@@ -4742,7 +4734,6 @@  vrp_prop::check_mem_ref (location_t location, tree
   else
     {
       eltsize = 1;
-      arrbounds[0] = 0;
       arrbounds[1] = wi::to_offset (TYPE_SIZE_UNIT (reftype));
     }
 
Index: gcc/testsuite/gfortran.dg/char_array_constructor_4.f90
===================================================================
--- gcc/testsuite/gfortran.dg/char_array_constructor_4.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/char_array_constructor_4.f90	(working copy)
@@ -0,0 +1,13 @@ 
+! PR 30319 - Bogus warning from -Warray-bounds during string assignment
+! { dg-do compile }
+! { dg-options "-O2 -Warray-bounds" }
+
+program test_bounds
+
+  character(256) :: foo
+
+  foo = '1234'                 ! { dg-bogus "\\\[-Warray-bounds" }
+
+  print *, foo
+
+end program test_bounds