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]

[gfortran] Fix PR 12704


The attached patch fixes PR fortran/12704 (broken MAXLOC and MINLOC with 
zero size arrays). The f95 standard does not specify what the returned 
value should be for zero size arrays, however f2k does.

Applied to tree-ssa branch.

Paul

2003-11-08  Paul Brook  <paul@nowt.org>

	PR fortran/12704
	* trans-intrinsic.c (gfc_conv_intrinsics_minmaxloc): Handle zero-size
	arrays.
libgfortran
	* m4/maxloc0.m4: Use default value of 1. Handle zero sized arrays.
	* m4/maxloc1.m4: Ditto.
	* m4/minloc0.m4: Ditto.
	* m4/minloc1.m4: Ditto.
	* m4/ifunction.m4: Set return value for zero sized arrays.
	* m4/iforeach.m4: Ditto.
	* m4/all.m4, m4/any.m4, m4/count.m4, m4/maxloc1.m4, m4/minloc1.m4, 
	m4/mxaval.m4, m4/minval.m4, m4/product.m4, m4/sum.m4: Ditto.
	* generated/*: Update.
testsuite
	* gfortran.fortran-toriture/execute/intrinsic_mmloc_3.f90: Extra test.
	* gfortran.fortran-toriture/execute/intrinsic_mmloc_4.f90: New test.
diff -uprxCVS -xgenerated clean/tree-ssa/gcc/fortran/trans-intrinsic.c gcc/gcc/fortran/trans-intrinsic.c
--- clean/tree-ssa/gcc/fortran/trans-intrinsic.c	2003-11-06 21:22:27.000000000 +0000
+++ gcc/gcc/fortran/trans-intrinsic.c	2003-11-08 14:47:11.000000000 +0000
@@ -1298,6 +1298,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
   tree type;
   tree tmp;
   tree ifbody;
+  tree cond;
   gfc_loopinfo loop;
   gfc_actual_arglist *actual;
   gfc_ss *arrayss;
@@ -1370,9 +1371,17 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
 
   assert (loop.dimen == 1);
 
-  /* Initialize the position to the first element.  This is neccessary
-     when all the values are equal to the limit.  */
-  gfc_add_modify_expr (&loop.pre, pos, loop.from[0]);
+  /* Initialize the position to the first element.  If the array has zero
+     size we need to return zero.  Otherwise use the first element of the
+     array, in case all elements are equal to the limit.
+     ie. pos = (ubound >= lbound) ? lbound, lbound - 1;  */
+  tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
+	             loop.from[0], integer_one_node));
+  cond = fold (build (GE_EXPR, boolean_type_node,
+		      loop.to[0], loop.from[0]));
+  tmp = fold (build (COND_EXPR, gfc_array_index_type, cond,
+		     loop.from[0], tmp));
+  gfc_add_modify_expr (&loop.pre, pos, tmp);
       
   gfc_mark_ss_chain_used (arrayss, 1);
   if (maskss)
diff -uprxCVS -xgenerated clean/tree-ssa/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f90 gcc/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f90
--- clean/tree-ssa/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f90	2003-11-06 20:55:38.000000000 +0000
+++ gcc/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f90	2003-11-08 12:44:41.000000000 +0000
@@ -1,8 +1,12 @@
 ! Check we do the right thing with extreme values.
 ! From PR12704
 program intrinsic_mmloc_3
-  integer, dimension(3) :: d
+  integer, dimension(2) :: d
+  integer, dimension(2,2) :: a
 
   d = -huge (d)
   if (maxloc (d, 1) .ne. 1) call abort()
+  a = huge (a)
+  d = minloc (a)
+  if (any (d .ne. 1)) call abort()
 end program
diff -uprxCVS -xgenerated clean/tree-ssa/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90 gcc/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90
--- clean/tree-ssa/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90	2003-11-08 12:46:50.000000000 +0000
+++ gcc/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90	2003-11-08 15:47:55.000000000 +0000
@@ -1,14 +1,15 @@
 ! Check zero sized arrays work correcly
 ! From PR12704
 program intrinsic_mmloc_4
-  integer, dimension(:) :: d
-  integer, dimension(:,:) :: a
+  integer, allocatable, dimension(:) :: d
+  integer, allocatable, dimension(:,:) :: a
   integer, dimension(2) :: b
 
   allocate (d(0))
-  if (maxloc (d, 1) .ne. 1) call abort()
+  print *, maxloc (d, 1)
+  if (maxloc (d, 1) .ne. 0) call abort()
   allocate (a(1, 0))
-  a = huge (a)
   b = minloc (a)
-  if (any (b .ne. 1)) call abort()
+  print *, b
+  if (any (b .ne. 0)) call abort()
 end program
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/all.m4 gcc/libgfortran/m4/all.m4
--- clean/tree-ssa/libgfortran/m4/all.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/all.m4	2003-11-08 13:45:08.000000000 +0000
@@ -26,7 +26,7 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(1,
 `  /* Return true only if all the elements are set.  */
   result = 1;',
 `  if (! *src)
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/any.m4 gcc/libgfortran/m4/any.m4
--- clean/tree-ssa/libgfortran/m4/any.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/any.m4	2003-11-08 13:56:13.000000000 +0000
@@ -26,7 +26,7 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(0,
 `  result = 0;',
 `  /* Return true if any of the elements are set.  */
   if (*src)
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/count.m4 gcc/libgfortran/m4/count.m4
--- clean/tree-ssa/libgfortran/m4/count.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/count.m4	2003-11-08 13:56:50.000000000 +0000
@@ -26,7 +26,7 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(0,
 `  result = 0;',
 `  if (*src)
     result++;')
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/iforeach.m4 gcc/libgfortran/m4/iforeach.m4
--- clean/tree-ssa/libgfortran/m4/iforeach.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/iforeach.m4	2003-11-08 15:53:01.000000000 +0000
@@ -25,17 +25,26 @@ define(START_FOREACH_FUNCTION,
     retarray->dim[0].stride = 1;
 
   dstride = retarray->dim[0].stride;
+  dest = retarray->data;
   for (n = 0; n < rank; n++)
     {
       sstride[n] = array->dim[n].stride;
       extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
       count[n] = 0;
       if (extent[n] <= 0)
-        return;
+	{
+	  /* Set the return value.  */
+	  for (n = 0; n < rank; n++)
+	    dest[n * dstride] = 0;
+	  return;
+	}
     }
 
   base = array->data;
-  dest = retarray->data;
+
+  /* Initialize the return value.  */
+  for (n = 0; n < rank; n++)
+    dest[n * dstride] = 1;
   {
 ')dnl
 define(START_FOREACH_BLOCK,
@@ -104,6 +113,7 @@ define(START_MASKED_FOREACH_FUNCTION,
     retarray->dim[0].stride = 1;
 
   dstride = retarray->dim[0].stride;
+  dest = retarray->data;
   for (n = 0; n < rank; n++)
     {
       sstride[n] = array->dim[n].stride;
@@ -111,10 +121,14 @@ define(START_MASKED_FOREACH_FUNCTION,
       extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
       count[n] = 0;
       if (extent[n] <= 0)
-        return;
+	{
+	  /* Set the return value.  */
+	  for (n = 0; n < rank; n++)
+	    dest[n * dstride] = 0;
+	  return;
+	}
     }
 
-  dest = retarray->data;
   base = array->data;
   mbase = mask->data;
 
@@ -127,6 +141,10 @@ define(START_MASKED_FOREACH_FUNCTION,
       mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
     }
 
+
+  /* Initialize the return value.  */
+  for (n = 0; n < rank; n++)
+    dest[n * dstride] = 1;
   {
 ')dnl
 define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/ifunction.m4 gcc/libgfortran/m4/ifunction.m4
--- clean/tree-ssa/libgfortran/m4/ifunction.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/ifunction.m4	2003-11-08 14:27:07.000000000 +0000
@@ -43,8 +43,6 @@ define(START_ARRAY_FUNCTION,
     retarray->dim[0].stride = 1;
 
   len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
-  if (len <= 0)
-    return;
   delta = array->dim[dim].stride;
 
   for (n = 0; n < dim; n++)
@@ -64,7 +62,7 @@ define(START_ARRAY_FUNCTION,
       count[n] = 0;
       dstride[n] = retarray->dim[n].stride;
       if (extent[n] <= 0)
-        return;
+        len = 0;
     }
 
   base = array->data;
@@ -78,12 +76,17 @@ define(START_ARRAY_FUNCTION,
       {
 ')dnl
 define(START_ARRAY_BLOCK,
-`       for (n = 0; n < len; n++, src += delta)
-          {
+`        if (len <= 0)
+	  *dest = '$1`;
+	else
+	  {
+	    for (n = 0; n < len; n++, src += delta)
+	      {
 ')dnl
 define(FINISH_ARRAY_FUNCTION,
-`          }
-        *dest = result;
+    `          }
+	    *dest = result;
+	  }
       }
       /* Advance to the next element.  */
       count[0]++;
@@ -194,12 +197,17 @@ define(START_MASKED_ARRAY_FUNCTION,
       {
 ')dnl
 define(START_MASKED_ARRAY_BLOCK,
-`        for (n = 0; n < len; n++, src += delta, msrc += mdelta)
-          {
+`        if (len <= 0)
+	  *dest = '$1`;
+	else
+	  {
+	    for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+	      {
 ')dnl
 define(FINISH_MASKED_ARRAY_FUNCTION,
-`          }
-        *dest = result;
+`              }
+	    *dest = result;
+	  }
       }
       /* Advance to the next element.  */
       count[0]++;
@@ -236,13 +244,13 @@ define(FINISH_MASKED_ARRAY_FUNCTION,
 }')dnl
 define(ARRAY_FUNCTION,
 `START_ARRAY_FUNCTION
-$1
-START_ARRAY_BLOCK
 $2
+START_ARRAY_BLOCK($1)
+$3
 FINISH_ARRAY_FUNCTION')dnl
 define(MASKED_ARRAY_FUNCTION,
 `START_MASKED_ARRAY_FUNCTION
-$1
-START_MASKED_ARRAY_BLOCK
 $2
+START_MASKED_ARRAY_BLOCK($1)
+$3
 FINISH_MASKED_ARRAY_FUNCTION')dnl
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/maxloc0.m4 gcc/libgfortran/m4/maxloc0.m4
--- clean/tree-ssa/libgfortran/m4/maxloc0.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/maxloc0.m4	2003-11-08 13:14:33.000000000 +0000
@@ -32,9 +32,6 @@ include(iforeach.m4)dnl
 FOREACH_FUNCTION(
 `  type_name maxval;
 
-  /* Initialize the return value.  */
-  for (n = 0; n < rank; n++)
-    dest[n * dstride] = 0;
   maxval = type_min;'
 ,
 `  if (*base > maxval)
@@ -47,9 +44,6 @@ FOREACH_FUNCTION(
 MASKED_FOREACH_FUNCTION(
 `  type_name maxval;
 
-  /* Initialize the return value.  */
-  for (n = 0; n < rank; n++)
-    dest[n * dstride] = 0;
   maxval = type_min;'
 ,
 `  if (*mbase && *base > maxval)
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/maxloc1.m4 gcc/libgfortran/m4/maxloc1.m4
--- clean/tree-ssa/libgfortran/m4/maxloc1.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/maxloc1.m4	2003-11-08 14:03:15.000000000 +0000
@@ -28,20 +28,20 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(0,
 `  type_name maxval;
   maxval = type_min;
-  result = 0;',
+  result = 1;',
 `  if (*src > maxval)
     {
       maxval = *src;
       result = (rtype_name)n + 1;
     }')
 
-MASKED_ARRAY_FUNCTION(
+MASKED_ARRAY_FUNCTION(0,
 `  type_name maxval;
   maxval = type_min;
-  result = 0;',
+  result = 1;',
 `  if (*msrc && *src > maxval)
     {
       maxval = *src;
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/maxval.m4 gcc/libgfortran/m4/maxval.m4
--- clean/tree-ssa/libgfortran/m4/maxval.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/maxval.m4	2003-11-08 14:03:34.000000000 +0000
@@ -27,12 +27,12 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(type_min,
 `  result = type_min;',
 `  if (*src > result)
     result = *src;')
 
-MASKED_ARRAY_FUNCTION(
+MASKED_ARRAY_FUNCTION(type_min,
 `  result = type_min;',
 `  if (*msrc && *src > result)
     result = *src;')
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/minloc0.m4 gcc/libgfortran/m4/minloc0.m4
--- clean/tree-ssa/libgfortran/m4/minloc0.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/minloc0.m4	2003-11-08 13:19:25.000000000 +0000
@@ -32,9 +32,6 @@ include(iforeach.m4)dnl
 FOREACH_FUNCTION(
 `  type_name minval;
 
-  /* Initialize the return value.  */
-  for (n = 0; n < rank; n++)
-    dest[n * dstride] = 0;
   minval = type_max;'
 ,
 `  if (*base < minval)
@@ -47,9 +44,6 @@ FOREACH_FUNCTION(
 MASKED_FOREACH_FUNCTION(
 `  type_name minval;
 
-  /* Initialize the return value.  */
-  for (n = 0; n < rank; n++)
-    dest[n * dstride] = 0;
   minval = type_max;'
 ,
 `  if (*mbase && *base < minval)
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/minloc1.m4 gcc/libgfortran/m4/minloc1.m4
--- clean/tree-ssa/libgfortran/m4/minloc1.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/minloc1.m4	2003-11-08 14:04:48.000000000 +0000
@@ -28,20 +28,20 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(0,
 `  type_name minval;
   minval = type_max;
-  result = 0;',
+  result = 1;',
 `  if (*src < minval)
     {
       minval = *src;
       result = (rtype_name)n + 1;
     }')
 
-MASKED_ARRAY_FUNCTION(
+MASKED_ARRAY_FUNCTION(0,
 `  type_name minval;
   minval = type_max;
-  result = 0;',
+  result = 1;',
 `  if (*msrc && *src < minval)
     {
       minval = *src;
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/minval.m4 gcc/libgfortran/m4/minval.m4
--- clean/tree-ssa/libgfortran/m4/minval.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/minval.m4	2003-11-08 14:05:00.000000000 +0000
@@ -27,12 +27,12 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(type_max,
 `  result = type_max;',
 `  if (*src < result)
     result = *src;')
 
-MASKED_ARRAY_FUNCTION(
+MASKED_ARRAY_FUNCTION(type_max,
 `  result = type_max;',
 `  if (*msrc && *src < result)
     result = *src;')
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/product.m4 gcc/libgfortran/m4/product.m4
--- clean/tree-ssa/libgfortran/m4/product.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/product.m4	2003-11-08 14:05:44.000000000 +0000
@@ -26,11 +26,11 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(1,
 `  result = 1;',
 `  result *= *src;')
 
-MASKED_ARRAY_FUNCTION(
+MASKED_ARRAY_FUNCTION(1,
 `  result = 1;',
 `  if (*msrc)
     result *= *src;')
diff -uprxCVS -xgenerated clean/tree-ssa/libgfortran/m4/sum.m4 gcc/libgfortran/m4/sum.m4
--- clean/tree-ssa/libgfortran/m4/sum.m4	2003-09-19 20:04:42.000000000 +0100
+++ gcc/libgfortran/m4/sum.m4	2003-11-08 14:05:55.000000000 +0000
@@ -26,11 +26,11 @@ Boston, MA 02111-1307, USA.  */
 
 include(iparm.m4)dnl
 include(ifunction.m4)dnl
-ARRAY_FUNCTION(
+ARRAY_FUNCTION(0,
 `  result = 0;',
 `  result += *src;')
 
-MASKED_ARRAY_FUNCTION(
+MASKED_ARRAY_FUNCTION(0,
 `  result = 0;',
 `  if (*msrc)
     result += *src;')

Attachment: intrinsic_mmloc_4.f90
Description: Text document


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