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] |
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] |