This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]