From: Tobias Burnus Date: Sat, 7 Jun 2008 18:53:07 +0000 (+0200) Subject: re PR fortran/36437 (Simplify argument to [c_]sizeof) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8d82b242392ea51ccdf17f4a2059425370c00b2a;p=gcc.git re PR fortran/36437 (Simplify argument to [c_]sizeof) 2008-06-04 Tobias Burnus 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 PR fortran/36437 * gfortran.dg/c_sizeof_1.f90: New. * gfortran.dg/c_sizeof_2.f90: New. From-SVN: r136536 --- 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 + + * 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 * 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2de14251fa5..2725962bf49 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-06-07 Tobias Burnus + + * gfortran.dg/c_sizeof_1.f90: New. + * gfortran.dg/c_sizeof_2.f90: New. + 2008-06-07 Joseph Myers * 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 index 00000000000..f2a5caf6864 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_sizeof_1.f90 @@ -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 index 00000000000..f6c3077f83d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_sizeof_2.f90 @@ -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 +