This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, Fortran] Implement F2008's c_sizeof (PR36437)
- From: Tobias Burnus <burnus at net-b dot de>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, "'fortran at gcc dot gnu dot org'" <fortran at gcc dot gnu dot org>
- Date: Thu, 05 Jun 2008 14:47:52 +0200
- Subject: [Patch, Fortran] Implement F2008's c_sizeof (PR36437)
This patch implements Fortran 2008's C_SIZEOF, which is a one liner. It
additionally does:
- Add documentation (essentially a copy from SIZEOF)
- Fix keyword= should be x= and not i=
- Simplify the generated tree. For scalars gfortran produced:
{
integer(kind=8) bytes.1;
i = 4;
}
and now it simpy generates: i = 4;
Build and "make check-gfortran pdf html" tested on x86-64-linux. OK for
the trunk?
Tobias
2008-06-05 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.
* intrinsic.texi: Add C_SIZEOF documentation.
2008-06-05 Tobias Burnus <burnus@net-b.de>
PR fortran/36437
* gfortran.dg/c_sizeof_1.f90: New.
* gfortran.dg/c_sizeof_2.f90: New.
Index: gcc/fortran/intrinsic.c
===================================================================
--- gcc/fortran/intrinsic.c (Revision 136393)
+++ gcc/fortran/intrinsic.c (Arbeitskopie)
@@ -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,
Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c (Revision 136393)
+++ gcc/fortran/trans-intrinsic.c (Arbeitskopie)
@@ -3265,8 +3265,6 @@ gfc_conv_intrinsic_sizeof (gfc_se *se, g
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, g
/* 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, g
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;
}
Index: gcc/fortran/intrinsic.texi
===================================================================
--- gcc/fortran/intrinsic.texi (Revision 136393)
+++ gcc/fortran/intrinsic.texi (Arbeitskopie)
@@ -75,6 +75,7 @@ Some basic guidelines for editing this d
* @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 thes
@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
Index: gcc/testsuite/gfortran.dg/c_sizeof_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/c_sizeof_1.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/c_sizeof_1.f90 (Revision 0)
@@ -0,0 +1,40 @@
+! { dg-do run }
+! Support F2003's c_sizeof()
+!
+integer(4) :: i, j(10)
+character(4),parameter :: str(1) = "abcd"
+
+! Using F2008's C_SIZEOF
+i = c_sizeof(i)
+if (i /= 4) call abort()
+
+i = c_sizeof(j)
+if (i /= 40) call abort()
+
+i = c_sizeof(str)
+if (i /= 4) call abort()
+
+i = c_sizeof(str(1))
+if (i /= 4) call abort()
+
+i = c_sizeof(str(1)(1:3))
+print *, i
+if (i /= 3) call abort()
+
+! Using GNU's SIZEOF
+i = sizeof(i)
+if (i /= 4) call abort()
+
+i = sizeof(j)
+if (i /= 40) call abort()
+
+i = sizeof(str)
+if (i /= 4) call abort()
+
+i = sizeof(str(1))
+if (i /= 4) call abort()
+
+i = sizeof(str(1)(1:3))
+if (i /= 3) call abort()
+end
+
Index: gcc/testsuite/gfortran.dg/c_sizeof_2.f90
===================================================================
--- gcc/testsuite/gfortran.dg/c_sizeof_2.f90 (Revision 0)
+++ gcc/testsuite/gfortran.dg/c_sizeof_2.f90 (Revision 0)
@@ -0,0 +1,9 @@
+! { dg-do compile }
+! { dg-options "-std=f2003 -Wall" }
+! Support F2003's c_sizeof()
+!
+integer(4) :: i, j(10)
+i = c_sizeof(i) ! { dg-error "not included in the selected standard" }
+i = c_sizeof(j) ! { dg-error "not included in the selected standard" }
+end
+