summaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2008-06-07 18:53:07 +0000
committerburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2008-06-07 18:53:07 +0000
commit189ffda53e4cfb127d2b5f013bc1156f811edb92 (patch)
tree8011d5b8270016bab53792cc7f926919d2a8d86a /gcc/fortran
parent6af9f7ea1f2b5cc8e19fc1f8d2d78f3a5dc02b6a (diff)
downloadgcc-189ffda53e4cfb127d2b5f013bc1156f811edb92.tar.gz
2008-06-04 Tobias Burnus <burnus@net-b.de>
PR fortran/36437 * intrinsic.c (add_functions): Implement c_sizeof. * trans-intrinsic.c (gfc_conv_intrinsic_sizeof): Do not create unneeded variable in the scalar case. 2008-06-04 Tobias Burnus <burnus@net-b.de> PR fortran/36437 * gfortran.dg/c_sizeof_1.f90: New. * gfortran.dg/c_sizeof_2.f90: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@136536 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog7
-rw-r--r--gcc/fortran/intrinsic.c3
-rw-r--r--gcc/fortran/intrinsic.texi55
-rw-r--r--gcc/fortran/trans-intrinsic.c12
4 files changed, 69 insertions, 8 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f34fddc2a10..a4c2fbf78e5 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,10 @@
+2008-06-07 Tobias Burnus <burnus@net-b.de>
+
+ * intrinsic.c (add_functions): Implement c_sizeof.
+ * trans-intrinsic.c (gfc_conv_intrinsic_sizeof): Do not
+ create unneeded variable in the scalar case.
+ * intrinsic.texi: Add C_SIZEOF documentation.
+
2008-06-06 Tobias Burnus <burnus@net-b.de>
* intrinsic.texi (BESSEL_J1): Fix BES(S)EL_J1 typo.
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 62ee442a19c..ebec5765ee5 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -2257,9 +2257,10 @@ add_functions (void)
add_sym_1 ("sizeof", GFC_ISYM_SIZEOF, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii,
GFC_STD_GNU, gfc_check_sizeof, NULL, NULL,
- i, BT_UNKNOWN, 0, REQUIRED);
+ x, BT_UNKNOWN, 0, REQUIRED);
make_generic ("sizeof", GFC_ISYM_SIZEOF, GFC_STD_GNU);
+ make_alias ("c_sizeof", GFC_STD_F2008);
add_sym_1 ("spacing", GFC_ISYM_SPACING, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
gfc_check_x, gfc_simplify_spacing, gfc_resolve_spacing,
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index a6259cc044e..ee358501bed 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -75,6 +75,7 @@ Some basic guidelines for editing this document:
* @code{C_F_PROCPOINTER}: C_F_PROCPOINTER, Convert C into Fortran procedure pointer
* @code{C_FUNLOC}: C_FUNLOC, Obtain the C address of a procedure
* @code{C_LOC}: C_LOC, Obtain the C address of an object
+* @code{C_SIZEOF}: C_SIZEOF, Size in bytes of an expression
* @code{CEILING}: CEILING, Integer ceiling function
* @code{CHAR}: CHAR, Integer-to-character conversion function
* @code{CHDIR}: CHDIR, Change working directory
@@ -2139,6 +2140,56 @@ end subroutine association_test
@end table
+@node C_SIZEOF
+@section @code{C_SIZEOF} --- Size in bytes of an expression
+@fnindex C_SIZEOF
+@cindex expression size
+@cindex size of an expression
+
+@table @asis
+@item @emph{Description}:
+@code{C_SIZEOF(X)} calculates the number of bytes of storage the
+expression @code{X} occupies.
+
+@item @emph{Standard}:
+Fortran 2008
+
+@item @emph{Class}:
+Intrinsic function
+
+@item @emph{Syntax}:
+@code{N = C_SIZEOF(X)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{X} @tab The argument shall be of any type, rank or shape.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type integer and of the system-dependent kind
+@var{C_SIZE_T} (from the @var{ISO_C_BINDING} module). Its value is the
+number of bytes occupied by the argument. If the argument has the
+@code{POINTER} attribute, the number of bytes of the storage area pointed
+to is returned. If the argument is of a derived type with @code{POINTER}
+or @code{ALLOCATABLE} components, the return value doesn't account for
+the sizes of the data pointed to by these components.
+
+@item @emph{Example}:
+@smallexample
+ use iso_c_binding
+ integer(c_int) :: i
+ real(c_float) :: r, s(5)
+ print *, (c_sizeof(s)/c_sizeof(r) == 5)
+ end
+@end smallexample
+The example will print @code{.TRUE.} unless you are using a platform
+where default @code{REAL} variables are unusually padded.
+
+@item @emph{See also}:
+@ref{SIZEOF}
+@end table
+
+
@node CEILING
@section @code{CEILING} --- Integer ceiling function
@fnindex CEILING
@@ -9870,8 +9921,12 @@ the sizes of the data pointed to by these components.
@end smallexample
The example will print @code{.TRUE.} unless you are using a platform
where default @code{REAL} variables are unusually padded.
+
+@item @emph{See also}:
+@ref{C_SIZEOF}
@end table
+
@node SLEEP
@section @code{SLEEP} --- Sleep for the specified number of seconds
@fnindex SLEEP
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 73e14a3f1fa..f1223933080 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -3265,8 +3265,6 @@ gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
gfc_init_se (&argse, NULL);
ss = gfc_walk_expr (arg);
- source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
-
if (ss == gfc_ss_terminator)
{
gfc_conv_expr_reference (&argse, arg);
@@ -3276,14 +3274,14 @@ gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
/* Obtain the source word length. */
if (arg->ts.type == BT_CHARACTER)
- source_bytes = size_of_string_in_bytes (arg->ts.kind,
- argse.string_length);
+ se->expr = size_of_string_in_bytes (arg->ts.kind,
+ argse.string_length);
else
- source_bytes = fold_convert (gfc_array_index_type,
- size_in_bytes (type));
+ se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
}
else
{
+ source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
argse.want_pointer = 0;
gfc_conv_expr_descriptor (&argse, arg, ss);
source = gfc_conv_descriptor_data_get (argse.expr);
@@ -3312,10 +3310,10 @@ gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
tmp, source_bytes);
gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
}
+ se->expr = source_bytes;
}
gfc_add_block_to_block (&se->pre, &argse.pre);
- se->expr = source_bytes;
}