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] |
Attached patch makes RESHAPE behaves correctly on zero-sized array sections (PR 27895). I don't know why I didn't spot it last time I looked, as it's really easy: at the start of the routine, when counting dimensions and extents, you simply use flags to mark if either source or pad arrays are zero-sized (the flags are named sempty, pempty). Then, before the main loop, you take the appropriate action.
This patch fixes an embarassing wrong-code bug, as wrong-code always are. Regtested on i686-linux (well, on a revision before the bootstrap breakage :) OK for mainline, 4.2 and 4.1?
Attachment:
reshape_zerosized.ChangeLog
Description: Binary data
Index: libgfortran/m4/reshape.m4 =================================================================== --- libgfortran/m4/reshape.m4 (revision 118156) +++ libgfortran/m4/reshape.m4 (working copy) @@ -38,9 +38,9 @@ typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type; -/* The shape parameter is ignored. We can currently deduce the shape from the - return array. */ -dnl Only the kind (ie size) is used to name the function. +dnl For integer routines, only the kind (ie size) is used to name the +dnl function. The same function will be used for integer and logical +dnl arrays of the same kind. extern void reshape_`'rtype_ccode (rtype * const restrict, rtype * const restrict, @@ -85,12 +85,13 @@ const rtype_name *src; int n; int dim; + int sempty, pempty; if (ret->data == NULL) { rdim = shape->dim[0].ubound - shape->dim[0].lbound + 1; rs = 1; - for (n=0; n < rdim; n++) + for (n = 0; n < rdim; n++) { ret->dim[n].lbound = 0; rex = shape->data[n * shape->dim[0].stride]; @@ -132,13 +133,17 @@ sdim = GFC_DESCRIPTOR_RANK (source); ssize = 1; + sempty = 0; for (n = 0; n < sdim; n++) { scount[n] = 0; sstride[n] = source->dim[n].stride; sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound; if (sextent[n] <= 0) - abort (); + { + sempty = 1; + sextent[n] = 0; + } if (ssize == sstride[n]) ssize *= sextent[n]; @@ -150,13 +155,18 @@ { pdim = GFC_DESCRIPTOR_RANK (pad); psize = 1; + pempty = 0; for (n = 0; n < pdim; n++) { pcount[n] = 0; pstride[n] = pad->dim[n].stride; pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound; if (pextent[n] <= 0) - abort (); + { + pempty = 1; + pextent[n] = 0; + } + if (psize == pstride[n]) psize *= pextent[n]; else @@ -168,6 +178,7 @@ { pdim = 0; psize = 1; + pempty = 1; pptr = NULL; } @@ -185,6 +196,24 @@ rstride0 = rstride[0]; sstride0 = sstride[0]; + if (sempty && pempty) + abort (); + + if (sempty) + { + /* Switch immediately to the pad array. */ + src = pptr; + sptr = NULL; + sdim = pdim; + for (dim = 0; dim < pdim; dim++) + { + scount[dim] = pcount[dim]; + sextent[dim] = pextent[dim]; + sstride[dim] = pstride[dim]; + sstride0 = sstride[0] * sizeof (rtype_name); + } + } + while (rptr) { /* Select between the source and pad arrays. */ @@ -194,6 +223,7 @@ src += sstride0; rcount[0]++; scount[0]++; + /* Advance to the next destination element. */ n = 0; while (rcount[n] == rextent[n]) Index: libgfortran/intrinsics/reshape_generic.c =================================================================== --- libgfortran/intrinsics/reshape_generic.c (revision 118156) +++ libgfortran/intrinsics/reshape_generic.c (working copy) @@ -37,9 +37,6 @@ typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type; typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) parray; -/* The shape parameter is ignored. We can currently deduce the shape from the - return array. */ - static void reshape_internal (parray *ret, parray *source, shape_type *shape, parray *pad, shape_type *order, index_type size) @@ -73,12 +70,13 @@ const char *src; int n; int dim; + int sempty, pempty; if (ret->data == NULL) { rdim = shape->dim[0].ubound - shape->dim[0].lbound + 1; rs = 1; - for (n=0; n < rdim; n++) + for (n = 0; n < rdim; n++) { ret->dim[n].lbound = 0; rex = shape->data[n * shape->dim[0].stride]; @@ -120,13 +118,17 @@ sdim = GFC_DESCRIPTOR_RANK (source); ssize = 1; + sempty = 0; for (n = 0; n < sdim; n++) { scount[n] = 0; sstride[n] = source->dim[n].stride; sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound; if (sextent[n] <= 0) - abort (); + { + sempty = 1; + sextent[n] = 0; + } if (ssize == sstride[n]) ssize *= sextent[n]; @@ -138,13 +140,18 @@ { pdim = GFC_DESCRIPTOR_RANK (pad); psize = 1; + pempty = 0; for (n = 0; n < pdim; n++) { pcount[n] = 0; pstride[n] = pad->dim[n].stride; pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound; if (pextent[n] <= 0) - abort (); + { + pempty = 1; + pextent[n] = 0; + } + if (psize == pstride[n]) psize *= pextent[n]; else @@ -156,6 +163,7 @@ { pdim = 0; psize = 1; + pempty = 1; pptr = NULL; } @@ -173,6 +181,24 @@ rstride0 = rstride[0] * size; sstride0 = sstride[0] * size; + if (sempty && pempty) + abort (); + + if (sempty) + { + /* Switch immediately to the pad array. */ + src = pptr; + sptr = NULL; + sdim = pdim; + for (dim = 0; dim < pdim; dim++) + { + scount[dim] = pcount[dim]; + sextent[dim] = pextent[dim]; + sstride[dim] = pstride[dim]; + sstride0 = sstride[0] * size; + } + } + while (rptr) { /* Select between the source and pad arrays. */ @@ -182,6 +208,7 @@ src += sstride0; rcount[0]++; scount[0]++; + /* Advance to the next destination element. */ n = 0; while (rcount[n] == rextent[n]) @@ -204,7 +231,8 @@ rcount[n]++; rptr += rstride[n] * size; } - } + } + /* Advance to the next source element. */ n = 0; while (scount[n] == sextent[n]) Index: gcc/testsuite/gfortran.dg/zero_sized_1.f90 =================================================================== --- gcc/testsuite/gfortran.dg/zero_sized_1.f90 (revision 118151) +++ gcc/testsuite/gfortran.dg/zero_sized_1.f90 (working copy) @@ -193,5 +193,5 @@ call test_unpack call test_spread call test_pack -! call test_reshape + call test_reshape end
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |