OSDN Git Service

* check.c (gfc_check_malloc, gfc_check_free): New functions.
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 30 Oct 2005 12:17:48 +0000 (12:17 +0000)
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 30 Oct 2005 12:17:48 +0000 (12:17 +0000)
* gfortran.h (gfc_generic_isym_id): Add GFC_ISYM_MALLOC.
* intrinsic.c (add_functions): Add symbols for MALLOC function.
(add_subroutines): Add symbol for FREE subroutine.
* intrinsic.h: Prototypes for gfc_check_malloc, gfc_check_free,
gfc_resolve_malloc and gfc_resolve_free.
* intrinsic.texi: Add doc for FREE and MALLOC intrinsics.
* iresolve.c (gfc_resolve_malloc, gfc_resolve_free): New
functions.
* trans-intrinsic.c (gfc_conv_intrinsic_function): Add case for
GFC_ISYM_MALLOC.

* Makefile.am: Add intrinsics/malloc.c file.
* Makefile.in: Regenerate.
* intrinsics/malloc.c: New file, with implementations for free
and malloc library functions.

* gfortran.dg/malloc_free_1.f90: New test.

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

13 files changed:
gcc/fortran/ChangeLog
gcc/fortran/check.c
gcc/fortran/gfortran.h
gcc/fortran/intrinsic.c
gcc/fortran/intrinsic.h
gcc/fortran/intrinsic.texi
gcc/fortran/iresolve.c
gcc/fortran/trans-intrinsic.c
gcc/testsuite/gfortran.dg/malloc_free_1.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/Makefile.am
libgfortran/Makefile.in
libgfortran/intrinsics/malloc.c [new file with mode: 0644]

index c28b1a9..2148c48 100644 (file)
@@ -1,3 +1,17 @@
+2005-10-30  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
+
+       * check.c (gfc_check_malloc, gfc_check_free): New functions.
+       * gfortran.h (gfc_generic_isym_id): Add GFC_ISYM_MALLOC.
+       * intrinsic.c (add_functions): Add symbols for MALLOC function.
+       (add_subroutines): Add symbol for FREE subroutine.
+       * intrinsic.h: Prototypes for gfc_check_malloc, gfc_check_free,
+       gfc_resolve_malloc and gfc_resolve_free.
+       * intrinsic.texi: Add doc for FREE and MALLOC intrinsics.
+       * iresolve.c (gfc_resolve_malloc, gfc_resolve_free): New
+       functions.
+       * trans-intrinsic.c (gfc_conv_intrinsic_function): Add case for
+       GFC_ISYM_MALLOC.
+
 2005-10-30  Steven Bosscher  <stevenb@suse.de>
 
        * gfortran.texi: Update contributors.
index d5218d3..6d2c65b 100644 (file)
@@ -1362,6 +1362,18 @@ gfc_check_min_max_double (gfc_actual_arglist * arg)
 
 /* End of min/max family.  */
 
+try
+gfc_check_malloc (gfc_expr * size)
+{
+  if (type_check (size, 0, BT_INTEGER) == FAILURE)
+    return FAILURE;
+
+  if (scalar_check (size, 0) == FAILURE)
+    return FAILURE;
+
+  return SUCCESS;
+}
+
 
 try
 gfc_check_matmul (gfc_expr * matrix_a, gfc_expr * matrix_b)
@@ -2621,6 +2633,19 @@ gfc_check_flush (gfc_expr * unit)
 
 
 try
+gfc_check_free (gfc_expr * i)
+{
+  if (type_check (i, 0, BT_INTEGER) == FAILURE)
+    return FAILURE;
+
+  if (scalar_check (i, 0) == FAILURE)
+    return FAILURE;
+
+  return SUCCESS;
+}
+
+
+try
 gfc_check_hostnm (gfc_expr * name)
 {
   if (type_check (name, 0, BT_CHARACTER) == FAILURE)
index 54bce8f..feff5af 100644 (file)
@@ -363,6 +363,7 @@ enum gfc_generic_isym_id
   GFC_ISYM_LOC,
   GFC_ISYM_LOG10,
   GFC_ISYM_LOGICAL,
+  GFC_ISYM_MALLOC,
   GFC_ISYM_MATMUL,
   GFC_ISYM_MAX,
   GFC_ISYM_MAXLOC,
index d414a05..e96ccbb 100644 (file)
@@ -1606,6 +1606,11 @@ add_functions (void)
 
   make_generic ("logical", GFC_ISYM_LOGICAL, GFC_STD_F95);
 
+  add_sym_1 ("malloc", 0, 1, BT_INTEGER, ii, GFC_STD_GNU, gfc_check_malloc,
+            NULL, gfc_resolve_malloc, a, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("malloc", GFC_ISYM_MALLOC, GFC_STD_GNU);
+
   add_sym_2 ("matmul", 0, 1, BT_REAL, dr, GFC_STD_F95,
             gfc_check_matmul, NULL, gfc_resolve_matmul,
             ma, BT_REAL, dr, REQUIRED, mb, BT_REAL, dr, REQUIRED);
@@ -2131,12 +2136,13 @@ add_subroutines (void)
     *trim_name = "trim_name", *ut = "unit", *han = "handler",
     *sec = "seconds";
 
-  int di, dr, dc, dl;
+  int di, dr, dc, dl, ii;
 
   di = gfc_default_integer_kind;
   dr = gfc_default_real_kind;
   dc = gfc_default_character_kind;
   dl = gfc_default_logical_kind;
+  ii = gfc_index_integer_kind;
 
   add_sym_0s ("abort", 1, GFC_STD_GNU, NULL);
 
@@ -2244,6 +2250,9 @@ add_subroutines (void)
              gfc_check_flush, NULL, gfc_resolve_flush,
              c, BT_INTEGER, di, OPTIONAL);
 
+  add_sym_1s ("free", 0, 1, BT_UNKNOWN, 0, GFC_STD_GNU, gfc_check_free,
+             NULL, gfc_resolve_free, c, BT_INTEGER, ii, REQUIRED);
+
   add_sym_2s ("hostnm", 0, 1, BT_UNKNOWN, 0, GFC_STD_GNU,
           gfc_check_hostnm_sub, NULL, gfc_resolve_hostnm_sub,
              c, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
index 556c6e4..eb25171 100644 (file)
@@ -83,6 +83,7 @@ try gfc_check_min_max (gfc_actual_arglist *);
 try gfc_check_min_max_integer (gfc_actual_arglist *);
 try gfc_check_min_max_real (gfc_actual_arglist *);
 try gfc_check_min_max_double (gfc_actual_arglist *);
+try gfc_check_malloc (gfc_expr *);
 try gfc_check_matmul (gfc_expr *, gfc_expr *);
 try gfc_check_merge (gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_minloc_maxloc (gfc_actual_arglist *);
@@ -134,6 +135,7 @@ try gfc_check_system_clock (gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_date_and_time (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_exit (gfc_expr *);
 try gfc_check_flush (gfc_expr *);
+try gfc_check_free (gfc_expr *);
 try gfc_check_fstat_sub (gfc_expr *, gfc_expr *, gfc_expr *);
 try gfc_check_gerror (gfc_expr *);
 try gfc_check_getlog (gfc_expr *);
@@ -335,6 +337,7 @@ void gfc_resolve_loc (gfc_expr *, gfc_expr *);
 void gfc_resolve_log (gfc_expr *, gfc_expr *);
 void gfc_resolve_log10 (gfc_expr *, gfc_expr *);
 void gfc_resolve_logical (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_malloc (gfc_expr *, gfc_expr *);
 void gfc_resolve_matmul (gfc_expr *, gfc_expr *, gfc_expr *);
 void gfc_resolve_max (gfc_expr *, gfc_actual_arglist *);
 void gfc_resolve_maxloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
@@ -394,6 +397,7 @@ void gfc_resolve_chdir_sub (gfc_code *);
 void gfc_resolve_cpu_time (gfc_code *);
 void gfc_resolve_exit (gfc_code *);
 void gfc_resolve_flush (gfc_code *);
+void gfc_resolve_free (gfc_code *);
 void gfc_resolve_fstat_sub (gfc_code *);
 void gfc_resolve_gerror (gfc_code *);
 void gfc_resolve_getarg (gfc_code *);
index 584391c..025b3f1 100644 (file)
@@ -88,9 +88,11 @@ and editing.  All contributions and corrections are strongly encouraged.
 * @code{EXPONENT}:      EXPONENT,  Exponent function
 * @code{FLOOR}:         FLOOR,     Integer floor function
 * @code{FNUM}:          FNUM,      File number function
+* @code{FREE}:          FREE,      Memory de-allocation subroutine
 * @code{LOC}:           LOC,       Returns the address of a variable
 * @code{LOG}:           LOG,       Logarithm function
 * @code{LOG10}:         LOG10,     Base 10 logarithm function 
+* @code{MALLOC}:        MALLOC,    Dynamic memory allocation function
 * @code{REAL}:          REAL,      Convert to real type 
 * @code{SIGNAL}:        SIGNAL,    Signal handling subroutine (or function)
 * @code{SIN}:           SIN,       Sine function
@@ -1757,7 +1759,7 @@ subroutine
 
 @item @emph{Arguments}:
 @multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be @code{REAL} with intent out.
+@item @var{X} @tab The type shall be @code{REAL} with @code{INTENT(OUT)}.
 @end multitable
 
 @item @emph{Return value}:
@@ -2697,6 +2699,41 @@ end program test_exponent
 @end table
 
 
+@node FREE
+@section @code{FREE} --- Frees memory
+@findex @code{FREE} intrinsic
+@cindex FREE
+
+@table @asis
+@item @emph{Description}:
+Frees memory previously allocated by @code{MALLOC()}. The @code{FREE}
+intrinsic is an extension intended to be used with Cray pointers, and is
+provided in @command{gfortran} to allow user to compile legacy code. For
+new code using Fortran 95 pointers, the memory de-allocation intrinsic is
+@code{DEALLOCATE}.
+
+@item @emph{Option}:
+gnu
+
+@item @emph{Class}:
+subroutine
+
+@item @emph{Syntax}:
+@code{FREE(PTR)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .80
+@item @var{PTR} @tab The type shall be @code{INTEGER}. It represents the
+location of the memory that should be de-allocated.
+@end multitable
+
+@item @emph{Return value}:
+None
+
+@item @emph{Example}:
+See @code{MALLOC} for an example.
+@end table
+
 
 @node FLOOR
 @section @code{FLOOR} --- Integer floor function
@@ -2918,6 +2955,68 @@ end program test_log10
 @end table
 
 
+@node MALLOC
+@section @code{MALLOC} --- Allocate dynamic memory
+@findex @code{MALLOC} intrinsic
+@cindex MALLOC
+
+@table @asis
+@item @emph{Description}:
+@code{MALLOC(SIZE)} allocates @var{SIZE} bytes of dynamic memory and
+returns the address of the allocated memory. The @code{MALLOC} intrinsic
+is an extension intended to be used with Cray pointers, and is provided
+in @command{gfortran} to allow user to compile legacy code. For new code
+using Fortran 95 pointers, the memory allocation intrinsic is
+@code{ALLOCATE}.
+
+@item @emph{Option}:
+gnu
+
+@item @emph{Class}:
+non-elemental function
+
+@item @emph{Syntax}:
+@code{PTR = MALLOC(SIZE)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .80
+@item @var{SIZE} @tab The type shall be @code{INTEGER(*)}.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type @code{INTEGER(K)}, with @var{K} such that
+variables of type @code{INTEGER(K)} have the same size as
+C pointers (@code{sizeof(void *)}).
+
+@item @emph{Example}:
+The following example demonstrates the use of @code{MALLOC} and
+@code{FREE} with Cray pointers. This example is intended to run on
+32-bit systems, where the default integer kind is suitable to store
+pointers; on 64-bit systems, ptr_x would need to be declared as
+@code{integer(kind=8)}.
+
+@smallexample
+program test_malloc
+  integer i
+  integer ptr_x
+  real*8 x(*), z
+  pointer(ptr_x,x)
+
+  ptr_x = malloc(20*8)
+  do i = 1, 20
+    x(i) = sqrt(1.0d0 / i)
+  end do
+  z = 0
+  do i = 1, 20
+    z = z + x(i)
+    print *, z
+  end do
+  call free(ptr_x)
+end program test_malloc
+@end smallexample
+@end table
+
+
 @node REAL
 @section @code{REAL} --- Convert to real type 
 @findex @code{REAL} intrinsic
index ae55aa7..5650c0f 100644 (file)
@@ -912,6 +912,24 @@ gfc_resolve_logical (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
 
 
 void
+gfc_resolve_malloc (gfc_expr * f, gfc_expr * size)
+{
+  if (size->ts.kind < gfc_index_integer_kind)
+    {
+      gfc_typespec ts;
+
+      ts.type = BT_INTEGER;
+      ts.kind = gfc_index_integer_kind;
+      gfc_convert_type_warn (size, &ts, 2, 0);
+    }
+
+  f->ts.type = BT_INTEGER;
+  f->ts.kind = gfc_index_integer_kind;
+  f->value.function.name = gfc_get_string (PREFIX("malloc"));
+}
+
+
+void
 gfc_resolve_matmul (gfc_expr * f, gfc_expr * a, gfc_expr * b)
 {
   gfc_expr temp;
@@ -2080,6 +2098,22 @@ gfc_resolve_flush (gfc_code * c)
 
 
 void
+gfc_resolve_free (gfc_code * c)
+{
+  gfc_typespec ts;
+  gfc_expr *n;
+
+  ts.type = BT_INTEGER;
+  ts.kind = gfc_index_integer_kind;
+  n = c->ext.actual->expr;
+  if (n->ts.kind != ts.kind)
+    gfc_convert_type (n, &ts, 2);
+
+  c->resolved_sym = gfc_get_intrinsic_sub_symbol (PREFIX("free"));
+}
+
+
+void
 gfc_resolve_gerror (gfc_code * c)
 {
   c->resolved_sym = gfc_get_intrinsic_sub_symbol (PREFIX ("gerror"));
index d14688b..93e8043 100644 (file)
@@ -3096,6 +3096,7 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
     case GFC_ISYM_IRAND:
     case GFC_ISYM_ISATTY:
     case GFC_ISYM_LINK:
+    case GFC_ISYM_MALLOC:
     case GFC_ISYM_MATMUL:
     case GFC_ISYM_RAND:
     case GFC_ISYM_RENAME:
diff --git a/gcc/testsuite/gfortran.dg/malloc_free_1.f90 b/gcc/testsuite/gfortran.dg/malloc_free_1.f90
new file mode 100644 (file)
index 0000000..4f03ef0
--- /dev/null
@@ -0,0 +1,11 @@
+! Test for the MALLOC and FREE intrinsics
+! If something is wrong with them, this test might segfault
+! { dg-do run }
+  integer j
+  integer*8 i8
+
+  do j = 1, 10000
+    i8 = malloc (10 * j)
+    call free (i8)
+  end do
+  end
index 9d225c1..85ea740 100644 (file)
@@ -1,3 +1,10 @@
+2005-10-30  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
+
+       * Makefile.am: Add intrinsics/malloc.c file.
+       * Makefile.in: Regenerate.
+       * intrinsics/malloc.c: New file, with implementations for free
+       and malloc library functions.
+
 2005-10-29  Mike Stump  <mrs@apple.com>
 
        * Makefile.am (kinds.h): Remove target, if command fails.
index 696ac3f..a786a38 100644 (file)
@@ -63,6 +63,7 @@ intrinsics/kill.c \
 intrinsics/ierrno.c \
 intrinsics/ishftc.c \
 intrinsics/link.c \
+intrinsics/malloc.c \
 intrinsics/mvbits.c \
 intrinsics/pack_generic.c \
 intrinsics/perror.c \
index d52a54a..b8f52d5 100644 (file)
@@ -169,8 +169,8 @@ am__objects_33 = associated.lo abort.lo args.lo bessel.lo \
        date_and_time.lo env.lo erf.lo eoshift0.lo eoshift2.lo \
        etime.lo exit.lo flush.lo fnum.lo gerror.lo getcwd.lo \
        getlog.lo getXid.lo hyper.lo hostnm.lo kill.lo ierrno.lo \
-       ishftc.lo link.lo mvbits.lo pack_generic.lo perror.lo \
-       signal.lo size.lo sleep.lo spread_generic.lo \
+       ishftc.lo link.lo malloc.lo mvbits.lo pack_generic.lo \
+       perror.lo signal.lo size.lo sleep.lo spread_generic.lo \
        string_intrinsics.lo system.lo rand.lo random.lo rename.lo \
        reshape_generic.lo reshape_packed.lo selected_int_kind.lo \
        selected_real_kind.lo stat.lo symlnk.lo system_clock.lo \
@@ -404,6 +404,7 @@ intrinsics/kill.c \
 intrinsics/ierrno.c \
 intrinsics/ishftc.c \
 intrinsics/link.c \
+intrinsics/malloc.c \
 intrinsics/mvbits.c \
 intrinsics/pack_generic.c \
 intrinsics/perror.c \
@@ -2291,6 +2292,9 @@ ishftc.lo: intrinsics/ishftc.c
 link.lo: intrinsics/link.c
        $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o link.lo `test -f 'intrinsics/link.c' || echo '$(srcdir)/'`intrinsics/link.c
 
+malloc.lo: intrinsics/malloc.c
+       $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o malloc.lo `test -f 'intrinsics/malloc.c' || echo '$(srcdir)/'`intrinsics/malloc.c
+
 mvbits.lo: intrinsics/mvbits.c
        $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mvbits.lo `test -f 'intrinsics/mvbits.c' || echo '$(srcdir)/'`intrinsics/mvbits.c
 
diff --git a/libgfortran/intrinsics/malloc.c b/libgfortran/intrinsics/malloc.c
new file mode 100644 (file)
index 0000000..2f53d99
--- /dev/null
@@ -0,0 +1,55 @@
+/* Implementation of the MALLOC and FREE intrinsics
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   Contributed by Fran├žois-Xavier Coudert <coudert@clipper.ens.fr>
+
+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., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+#include "config.h"
+#include "libgfortran.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+extern void PREFIX(free) (void **);
+export_proto_np(PREFIX(free));
+
+void
+PREFIX(free) (void ** ptr)
+{
+  free (*ptr);
+}
+
+
+extern void * PREFIX(malloc) (size_t *);
+export_proto_np(PREFIX(malloc));
+
+void *
+PREFIX(malloc) (size_t * size)
+{
+  return malloc (*size);
+}