aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <coudert@clipper.ens.fr>2005-10-30 13:17:48 +0100
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>2005-10-30 12:17:48 +0000
commit0d519038a0354f983534037fd9a7d460421e4fd0 (patch)
tree74008967faaa4d2ec3fb686ef0f09df588ecbd88
parentcf6ae9554d33bc2afe113135a0f34d5022bb1972 (diff)
downloadgcc-0d519038a0354f983534037fd9a7d460421e4fd0.zip
gcc-0d519038a0354f983534037fd9a7d460421e4fd0.tar.gz
gcc-0d519038a0354f983534037fd9a7d460421e4fd0.tar.bz2
check.c (gfc_check_malloc, [...]): New functions.
* 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. * 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. From-SVN: r106016
-rw-r--r--gcc/fortran/ChangeLog14
-rw-r--r--gcc/fortran/check.c25
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/intrinsic.c11
-rw-r--r--gcc/fortran/intrinsic.h4
-rw-r--r--gcc/fortran/intrinsic.texi101
-rw-r--r--gcc/fortran/iresolve.c34
-rw-r--r--gcc/fortran/trans-intrinsic.c1
-rw-r--r--gcc/testsuite/gfortran.dg/malloc_free_1.f9011
-rw-r--r--libgfortran/ChangeLog7
-rw-r--r--libgfortran/Makefile.am1
-rw-r--r--libgfortran/Makefile.in8
-rw-r--r--libgfortran/intrinsics/malloc.c55
13 files changed, 269 insertions, 4 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c28b1a9..2148c48 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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.
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index d5218d3..6d2c65b 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -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)
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 54bce8f..feff5af 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -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,
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index d414a05..e96ccbb 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -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);
diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h
index 556c6e4..eb25171 100644
--- a/gcc/fortran/intrinsic.h
+++ b/gcc/fortran/intrinsic.h
@@ -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 *);
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 584391c..025b3f1a 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -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
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
index ae55aa7..5650c0f 100644
--- a/gcc/fortran/iresolve.c
+++ b/gcc/fortran/iresolve.c
@@ -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"));
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index d14688b..93e8043 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -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
index 0000000..4f03ef0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/malloc_free_1.f90
@@ -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
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 9d225c1..85ea740 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -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.
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index 696ac3f..a786a38 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -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 \
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index d52a54a..b8f52d5 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -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
index 0000000..2f53d99
--- /dev/null
+++ b/libgfortran/intrinsics/malloc.c
@@ -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);
+}