OSDN Git Service

2005-05-18 Thomas Koenig <Thomas.Koenig@online.de>
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 May 2005 20:24:32 +0000 (20:24 +0000)
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 May 2005 20:24:32 +0000 (20:24 +0000)
        PR libfortran/21127
        * Makefile.am:  Add generated/reshape_c4.c and
        generated/reshape_c8.c.
        * Makefile.in:  Regenerated.
        * m4/iparm.m4:  Define rtype_ccode to be c4 or c8 for
        complex types, 4 or 8 otherwise.
        * m4/reshape.m4:  Use rtype_ccode instead of rtype_kind
        in function name.
        * generated/reshape_c4.c: New file.
        * generated/reshape_c8.c: New file.

2005-05-18  Thomas Koenig  <Thomas.Koenig@online.de>

        PR libfortran/21127
        * fortran/iresolve.c (gfc_resolve_reshape): Add
        gfc_type_letter (BT_COMPLEX) for complex to
        to resolved function name.

2005-05-18  Thomas Koenig  <Thomas.Koenig@online.de>

        PR libfortran/21127
        * gfortran.dg/reshape-complex.f90:  New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99925 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/iresolve.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/reshape-complex.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/generated/reshape_c4.c [new file with mode: 0644]
libgfortran/generated/reshape_c8.c [new file with mode: 0644]
libgfortran/m4/iparm.m4
libgfortran/m4/reshape.m4

index 31179f0..87e1047 100644 (file)
@@ -1,3 +1,10 @@
+2005-05-18  Thomas Koenig  <Thomas.Koenig@online.de>
+
+       PR libfortran/21127
+       * fortran/iresolve.c (gfc_resolve_reshape): Add 
+       gfc_type_letter (BT_COMPLEX) for complex to
+       to resolved function name.
+
 2005-05-18 Erik Edelmann <erik.edelmann@iki.fi>
 
        * array.c (gfc_match_array_constructor): Support [ ... ]
index 746b97d..e939287 100644 (file)
@@ -1137,8 +1137,14 @@ gfc_resolve_reshape (gfc_expr * f, gfc_expr * source, gfc_expr * shape,
     case 4:
     case 8:
     /* case 16: */
-      f->value.function.name =
-       gfc_get_string (PREFIX("reshape_%d"), source->ts.kind);
+      if (source->ts.type == BT_COMPLEX)
+       f->value.function.name =
+         gfc_get_string (PREFIX("reshape_%c%d"),
+                         gfc_type_letter (BT_COMPLEX), source->ts.kind);
+      else
+       f->value.function.name =
+         gfc_get_string (PREFIX("reshape_%d"), source->ts.kind);
+
       break;
 
     default:
index 7ee682a..74b3701 100644 (file)
@@ -1,3 +1,8 @@
+2005-05-18  Thomas Koenig  <Thomas.Koenig@online.de>
+
+       PR libfortran/21127
+       * gfortran.dg/reshape-complex.f90:  New test.
+
 2005-05-18  Erik Edelmann  <erik.edelmann@iki.fi>
 
        * gfortran.dg/array_constructor_1.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/reshape-complex.f90 b/gcc/testsuite/gfortran.dg/reshape-complex.f90
new file mode 100644 (file)
index 0000000..87c8049
--- /dev/null
@@ -0,0 +1,11 @@
+! { dg-do run }
+! PR 21127:  Reshape of complex didn't work.
+program main
+  complex, dimension(8) :: b
+  complex, dimension(2,2) :: a
+  integer :: i
+  b = (/(i,i=1,8)/)
+  a = reshape(b(1:8:2),shape(a))
+  if (a(1,1) /= (1.0, 0.0) .or. a(2,1) /= (3.0, 0.0) .or.  &
+      a(1,2) /= (5.0, 0.0) .or. a(2,2) /= (7.0, 0.0)) call abort
+end
index 11fe6d5..f2e7bfd 100644 (file)
@@ -1,3 +1,16 @@
+2005-05-18  Thomas Koenig  <Thomas.Koenig@online.de>
+
+       PR libfortran/21127
+       * Makefile.am:  Add generated/reshape_c4.c and
+       generated/reshape_c8.c.
+       * Makefile.in:  Regenerated.
+       * m4/iparm.m4:  Define rtype_ccode to be c4 or c8 for
+       complex types, 4 or 8 otherwise.
+       * m4/reshape.m4:  Use rtype_ccode instead of rtype_kind
+       in function name.
+       * generated/reshape_c4.c: New file.
+       * generated/reshape_c8.c: New file.
+
 2005-05-16  Andreas Jaeger  <aj@suse.de>
 
        * configure.ac: Add additional warning flags.
diff --git a/libgfortran/generated/reshape_c4.c b/libgfortran/generated/reshape_c4.c
new file mode 100644 (file)
index 0000000..02d73d2
--- /dev/null
@@ -0,0 +1,258 @@
+/* Implementation of the RESHAPE
+   Copyright 2002 Free Software Foundation, Inc.
+   Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+Libgfortran is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with libgfortran; see the file COPYING.  If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
+
+/* The shape parameter is ignored. We can currently deduce the shape from the
+   return array.  */
+
+extern void reshape_c4 (gfc_array_c4 *, gfc_array_c4 *, shape_type *,
+                                   gfc_array_c4 *, shape_type *);
+export_proto(reshape_c4);
+
+void
+reshape_c4 (gfc_array_c4 * ret, gfc_array_c4 * source, shape_type * shape,
+                      gfc_array_c4 * pad, shape_type * order)
+{
+  /* r.* indicates the return array.  */
+  index_type rcount[GFC_MAX_DIMENSIONS];
+  index_type rextent[GFC_MAX_DIMENSIONS];
+  index_type rstride[GFC_MAX_DIMENSIONS];
+  index_type rstride0;
+  index_type rdim;
+  index_type rsize;
+  index_type rs;
+  index_type rex;
+  GFC_COMPLEX_4 *rptr;
+  /* s.* indicates the source array.  */
+  index_type scount[GFC_MAX_DIMENSIONS];
+  index_type sextent[GFC_MAX_DIMENSIONS];
+  index_type sstride[GFC_MAX_DIMENSIONS];
+  index_type sstride0;
+  index_type sdim;
+  index_type ssize;
+  const GFC_COMPLEX_4 *sptr;
+  /* p.* indicates the pad array.  */
+  index_type pcount[GFC_MAX_DIMENSIONS];
+  index_type pextent[GFC_MAX_DIMENSIONS];
+  index_type pstride[GFC_MAX_DIMENSIONS];
+  index_type pdim;
+  index_type psize;
+  const GFC_COMPLEX_4 *pptr;
+
+  const GFC_COMPLEX_4 *src;
+  int n;
+  int dim;
+
+  if (source->dim[0].stride == 0)
+    source->dim[0].stride = 1;
+  if (shape->dim[0].stride == 0)
+    shape->dim[0].stride = 1;
+  if (pad && pad->dim[0].stride == 0)
+    pad->dim[0].stride = 1;
+  if (order && order->dim[0].stride == 0)
+    order->dim[0].stride = 1;
+
+  if (ret->data == NULL)
+    {
+      rdim = shape->dim[0].ubound - shape->dim[0].lbound + 1;
+      rs = 1;
+      for (n=0; n < rdim; n++)
+       {
+         ret->dim[n].lbound = 0;
+         rex = shape->data[n * shape->dim[0].stride];
+         ret->dim[n].ubound =  rex - 1;
+         ret->dim[n].stride = rs;
+         rs *= rex;
+       }
+      ret->base = 0;
+      ret->data = internal_malloc_size ( rs * sizeof (GFC_COMPLEX_4));
+      ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
+    }
+  else
+    {
+      rdim = GFC_DESCRIPTOR_RANK (ret);
+      if (ret->dim[0].stride == 0)
+       ret->dim[0].stride = 1;
+    }
+
+  rsize = 1;
+  for (n = 0; n < rdim; n++)
+    {
+      if (order)
+        dim = order->data[n * order->dim[0].stride] - 1;
+      else
+        dim = n;
+
+      rcount[n] = 0;
+      rstride[n] = ret->dim[dim].stride;
+      rextent[n] = ret->dim[dim].ubound + 1 - ret->dim[dim].lbound;
+
+      if (rextent[n] != shape->data[dim * shape->dim[0].stride])
+        runtime_error ("shape and target do not conform");
+
+      if (rsize == rstride[n])
+        rsize *= rextent[n];
+      else
+        rsize = 0;
+      if (rextent[n] <= 0)
+        return;
+    }
+
+  sdim = GFC_DESCRIPTOR_RANK (source);
+  ssize = 1;
+  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 ();
+
+      if (ssize == sstride[n])
+        ssize *= sextent[n];
+      else
+        ssize = 0;
+    }
+
+  if (pad)
+    {
+      pdim = GFC_DESCRIPTOR_RANK (pad);
+      psize = 1;
+      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 ();
+          if (psize == pstride[n])
+            psize *= pextent[n];
+          else
+            psize = 0;
+        }
+      pptr = pad->data;
+    }
+  else
+    {
+      pdim = 0;
+      psize = 1;
+      pptr = NULL;
+    }
+
+  if (rsize != 0 && ssize != 0 && psize != 0)
+    {
+      rsize *= 4;
+      ssize *= 4;
+      psize *= 4;
+      reshape_packed ((char *)ret->data, rsize, (char *)source->data,
+                     ssize, pad ? (char *)pad->data : NULL, psize);
+      return;
+    }
+  rptr = ret->data;
+  src = sptr = source->data;
+  rstride0 = rstride[0];
+  sstride0 = sstride[0];
+
+  while (rptr)
+    {
+      /* Select between the source and pad arrays.  */
+      *rptr = *src;
+      /* Advance to the next element.  */
+      rptr += rstride0;
+      src += sstride0;
+      rcount[0]++;
+      scount[0]++;
+      /* Advance to the next destination element.  */
+      n = 0;
+      while (rcount[n] == rextent[n])
+        {
+          /* When we get to the end of a dimension, reset it and increment
+             the next dimension.  */
+          rcount[n] = 0;
+          /* We could precalculate these products, but this is a less
+             frequently used path so proabably not worth it.  */
+          rptr -= rstride[n] * rextent[n];
+          n++;
+          if (n == rdim)
+            {
+              /* Break out of the loop.  */
+              rptr = NULL;
+              break;
+            }
+          else
+            {
+              rcount[n]++;
+              rptr += rstride[n];
+            }
+        }
+      /* Advance to the next source element.  */
+      n = 0;
+      while (scount[n] == sextent[n])
+        {
+          /* When we get to the end of a dimension, reset it and increment
+             the next dimension.  */
+          scount[n] = 0;
+          /* We could precalculate these products, but this is a less
+             frequently used path so proabably not worth it.  */
+          src -= sstride[n] * sextent[n];
+          n++;
+          if (n == sdim)
+            {
+              if (sptr && pad)
+                {
+                  /* Switch to the pad array.  */
+                  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];
+                    }
+                }
+              /* We now start again from the beginning of the pad array.  */
+              src = pptr;
+              break;
+            }
+          else
+            {
+              scount[n]++;
+              src += sstride[n];
+            }
+        }
+    }
+}
diff --git a/libgfortran/generated/reshape_c8.c b/libgfortran/generated/reshape_c8.c
new file mode 100644 (file)
index 0000000..e6ddf1a
--- /dev/null
@@ -0,0 +1,258 @@
+/* Implementation of the RESHAPE
+   Copyright 2002 Free Software Foundation, Inc.
+   Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+Libgfortran is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with libgfortran; see the file COPYING.  If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
+
+/* The shape parameter is ignored. We can currently deduce the shape from the
+   return array.  */
+
+extern void reshape_c8 (gfc_array_c8 *, gfc_array_c8 *, shape_type *,
+                                   gfc_array_c8 *, shape_type *);
+export_proto(reshape_c8);
+
+void
+reshape_c8 (gfc_array_c8 * ret, gfc_array_c8 * source, shape_type * shape,
+                      gfc_array_c8 * pad, shape_type * order)
+{
+  /* r.* indicates the return array.  */
+  index_type rcount[GFC_MAX_DIMENSIONS];
+  index_type rextent[GFC_MAX_DIMENSIONS];
+  index_type rstride[GFC_MAX_DIMENSIONS];
+  index_type rstride0;
+  index_type rdim;
+  index_type rsize;
+  index_type rs;
+  index_type rex;
+  GFC_COMPLEX_8 *rptr;
+  /* s.* indicates the source array.  */
+  index_type scount[GFC_MAX_DIMENSIONS];
+  index_type sextent[GFC_MAX_DIMENSIONS];
+  index_type sstride[GFC_MAX_DIMENSIONS];
+  index_type sstride0;
+  index_type sdim;
+  index_type ssize;
+  const GFC_COMPLEX_8 *sptr;
+  /* p.* indicates the pad array.  */
+  index_type pcount[GFC_MAX_DIMENSIONS];
+  index_type pextent[GFC_MAX_DIMENSIONS];
+  index_type pstride[GFC_MAX_DIMENSIONS];
+  index_type pdim;
+  index_type psize;
+  const GFC_COMPLEX_8 *pptr;
+
+  const GFC_COMPLEX_8 *src;
+  int n;
+  int dim;
+
+  if (source->dim[0].stride == 0)
+    source->dim[0].stride = 1;
+  if (shape->dim[0].stride == 0)
+    shape->dim[0].stride = 1;
+  if (pad && pad->dim[0].stride == 0)
+    pad->dim[0].stride = 1;
+  if (order && order->dim[0].stride == 0)
+    order->dim[0].stride = 1;
+
+  if (ret->data == NULL)
+    {
+      rdim = shape->dim[0].ubound - shape->dim[0].lbound + 1;
+      rs = 1;
+      for (n=0; n < rdim; n++)
+       {
+         ret->dim[n].lbound = 0;
+         rex = shape->data[n * shape->dim[0].stride];
+         ret->dim[n].ubound =  rex - 1;
+         ret->dim[n].stride = rs;
+         rs *= rex;
+       }
+      ret->base = 0;
+      ret->data = internal_malloc_size ( rs * sizeof (GFC_COMPLEX_8));
+      ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
+    }
+  else
+    {
+      rdim = GFC_DESCRIPTOR_RANK (ret);
+      if (ret->dim[0].stride == 0)
+       ret->dim[0].stride = 1;
+    }
+
+  rsize = 1;
+  for (n = 0; n < rdim; n++)
+    {
+      if (order)
+        dim = order->data[n * order->dim[0].stride] - 1;
+      else
+        dim = n;
+
+      rcount[n] = 0;
+      rstride[n] = ret->dim[dim].stride;
+      rextent[n] = ret->dim[dim].ubound + 1 - ret->dim[dim].lbound;
+
+      if (rextent[n] != shape->data[dim * shape->dim[0].stride])
+        runtime_error ("shape and target do not conform");
+
+      if (rsize == rstride[n])
+        rsize *= rextent[n];
+      else
+        rsize = 0;
+      if (rextent[n] <= 0)
+        return;
+    }
+
+  sdim = GFC_DESCRIPTOR_RANK (source);
+  ssize = 1;
+  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 ();
+
+      if (ssize == sstride[n])
+        ssize *= sextent[n];
+      else
+        ssize = 0;
+    }
+
+  if (pad)
+    {
+      pdim = GFC_DESCRIPTOR_RANK (pad);
+      psize = 1;
+      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 ();
+          if (psize == pstride[n])
+            psize *= pextent[n];
+          else
+            psize = 0;
+        }
+      pptr = pad->data;
+    }
+  else
+    {
+      pdim = 0;
+      psize = 1;
+      pptr = NULL;
+    }
+
+  if (rsize != 0 && ssize != 0 && psize != 0)
+    {
+      rsize *= 8;
+      ssize *= 8;
+      psize *= 8;
+      reshape_packed ((char *)ret->data, rsize, (char *)source->data,
+                     ssize, pad ? (char *)pad->data : NULL, psize);
+      return;
+    }
+  rptr = ret->data;
+  src = sptr = source->data;
+  rstride0 = rstride[0];
+  sstride0 = sstride[0];
+
+  while (rptr)
+    {
+      /* Select between the source and pad arrays.  */
+      *rptr = *src;
+      /* Advance to the next element.  */
+      rptr += rstride0;
+      src += sstride0;
+      rcount[0]++;
+      scount[0]++;
+      /* Advance to the next destination element.  */
+      n = 0;
+      while (rcount[n] == rextent[n])
+        {
+          /* When we get to the end of a dimension, reset it and increment
+             the next dimension.  */
+          rcount[n] = 0;
+          /* We could precalculate these products, but this is a less
+             frequently used path so proabably not worth it.  */
+          rptr -= rstride[n] * rextent[n];
+          n++;
+          if (n == rdim)
+            {
+              /* Break out of the loop.  */
+              rptr = NULL;
+              break;
+            }
+          else
+            {
+              rcount[n]++;
+              rptr += rstride[n];
+            }
+        }
+      /* Advance to the next source element.  */
+      n = 0;
+      while (scount[n] == sextent[n])
+        {
+          /* When we get to the end of a dimension, reset it and increment
+             the next dimension.  */
+          scount[n] = 0;
+          /* We could precalculate these products, but this is a less
+             frequently used path so proabably not worth it.  */
+          src -= sstride[n] * sextent[n];
+          n++;
+          if (n == sdim)
+            {
+              if (sptr && pad)
+                {
+                  /* Switch to the pad array.  */
+                  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];
+                    }
+                }
+              /* We now start again from the beginning of the pad array.  */
+              src = pptr;
+              break;
+            }
+          else
+            {
+              scount[n]++;
+              src += sstride[n];
+            }
+        }
+    }
+}
index b9de993..810f78c 100644 (file)
@@ -30,3 +30,4 @@ define(rtype_qual,`_'rtype_kind)dnl
 define(atype_max, atype_name`_HUGE')dnl
 define(atype_min, `-'atype_max)dnl
 define(name, regexp(regexp(file, `[^/]*$', `\&'), `^\([^_]*\)_', `\1'))dnl
+define(rtype_ccode,ifelse(rtype_letter,`c',rtype_code,rtype_kind))dnl
index 541377f..6b411f0 100644 (file)
@@ -40,12 +40,12 @@ typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
    return array.  */
 dnl Only the kind (ie size) is used to name the function.
 
-extern void reshape_`'rtype_kind (rtype *, rtype *, shape_type *,
+extern void reshape_`'rtype_ccode (rtype *, rtype *, shape_type *,
                                    rtype *, shape_type *);
-export_proto(reshape_`'rtype_kind);
+export_proto(reshape_`'rtype_ccode);
 
 void
-reshape_`'rtype_kind (rtype * ret, rtype * source, shape_type * shape,
+reshape_`'rtype_ccode (rtype * ret, rtype * source, shape_type * shape,
                       rtype * pad, shape_type * order)
 {
   /* r.* indicates the return array.  */