re PR fortran/36437 (Simplify argument to [c_]sizeof)
authorTobias Burnus <burnus@net-b.de>
Sat, 7 Jun 2008 18:53:07 +0000 (20:53 +0200)
committerTobias Burnus <burnus@gcc.gnu.org>
Sat, 7 Jun 2008 18:53:07 +0000 (20:53 +0200)
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.

From-SVN: r136536

gcc/fortran/ChangeLog
gcc/fortran/intrinsic.c
gcc/fortran/intrinsic.texi
gcc/fortran/trans-intrinsic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/c_sizeof_1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/c_sizeof_2.f90 [new file with mode: 0644]

index f34fddc2a101453b758743b6642c56f18f4eefa9..a4c2fbf78e57044dbfaf8bc4f36e82dfb4f273ab 100644 (file)
@@ -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.
index 62ee442a19cc92224040e75e58a50e446e81a483..ebec5765ee52371fd113555b2618c3f8beb3e49d 100644 (file)
@@ -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 a6259cc044e6ee177fcc42c2b85e6a9eaedb4979..ee358501bed8629052f9e051bcb672a99dec180f 100644 (file)
@@ -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
index 73e14a3f1faa5aeba70bdb46c5696df64a7ae349..f12239330809fde887fbdea24d3c0db7112a1275 100644 (file)
@@ -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;
 }
 
 
index 2de14251fa58804725860c56c359f3f40b8d7625..2725962bf4989243f230f3f71c98d8ccd1576a20 100644 (file)
@@ -1,3 +1,8 @@
+2008-06-07  Tobias Burnus  <burnus@net-b.de>
+
+       * gfortran.dg/c_sizeof_1.f90: New.
+       * gfortran.dg/c_sizeof_2.f90: New.
+
 2008-06-07  Joseph Myers  <joseph@codesourcery.com>
 
        * g++.dg/abi/arm_cxa_vec1.C: Don't handle xscale*-*-*.
diff --git a/gcc/testsuite/gfortran.dg/c_sizeof_1.f90 b/gcc/testsuite/gfortran.dg/c_sizeof_1.f90
new file mode 100644 (file)
index 0000000..f2a5caf
--- /dev/null
@@ -0,0 +1,40 @@
+! { dg-do run }
+! Support F2008'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
+
diff --git a/gcc/testsuite/gfortran.dg/c_sizeof_2.f90 b/gcc/testsuite/gfortran.dg/c_sizeof_2.f90
new file mode 100644 (file)
index 0000000..f6c3077
--- /dev/null
@@ -0,0 +1,9 @@
+! { dg-do compile }
+! { dg-options "-std=f2003 -Wall" }
+! Support F2008'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
+