Patchwork [Fortran] PR 51842 use ptrdiff_t for array indices

login
register
mail settings
Submitter Tobias Burnus
Date Jan. 13, 2012, 2:07 p.m.
Message ID <4F103A8E.3020702@net-b.de>
Download mbox | patch
Permalink /patch/135844/
State New
Headers show

Comments

Tobias Burnus - Jan. 13, 2012, 2:07 p.m.
Dear all,

the front end uses for array indices (gfc_index_integer_kind / 
gfc_array_index_type) which is a signed integer of size POINTER_SIZE.

The libgfortran library used to use
    typedef ssize_t index_type;
which fails if sizeof(void*) is not sizeof(ssize_t); the latter is the 
case on LP64 systems (see PR).

For 4.7 this was changed (in April 2011) to:
     typedef ptrdiff_t index_type;
which makes more sense - and should be sufficient for LP64 systems.

However, mixing an POINTER_SIZE type with ptrdiff_t only works if 
sizeof(ptrdiff_t) == POINTER_SIZE; in principle, the maximally allowed 
size of a variable can be smaller (e.g. page size) than the maximally 
allowed pointer size. (sizeof() returns a result of type size_t). I do 
not know whether such systems exist in practice and whether such a 
system is supported by GCC.

The attached patch makes let's the FE emit code of the same data type as 
used in libgfortran - ptrdiff_t for the array indices.

Build and regtested on x86-64-linux.
OK for the trunk?

Tobias
Janne Blomqvist - Jan. 13, 2012, 3:30 p.m.
On Fri, Jan 13, 2012 at 16:07, Tobias Burnus <burnus@net-b.de> wrote:
> Dear all,
>
> the front end uses for array indices (gfc_index_integer_kind /
> gfc_array_index_type) which is a signed integer of size POINTER_SIZE.
>
> The libgfortran library used to use
>   typedef ssize_t index_type;
> which fails if sizeof(void*) is not sizeof(ssize_t); the latter is the case
> on LP64 systems (see PR).

As a minor nitpick, not necessarily: E.g. x86_64-linux-gnu and most
64-bit Unix targets are also LP64 (as in, long and pointer are 64
bits), but older releases work there as ssize_t is also 64 bits. The
target in the PR is (was?) thus a bit "special", in that while it's
LP64, ssize_t is smaller than 64 bits.

> For 4.7 this was changed (in April 2011) to:
>    typedef ptrdiff_t index_type;
> which makes more sense - and should be sufficient for LP64 systems.
>
> However, mixing an POINTER_SIZE type with ptrdiff_t only works if
> sizeof(ptrdiff_t) == POINTER_SIZE; in principle, the maximally allowed size
> of a variable can be smaller (e.g. page size) than the maximally allowed
> pointer size. (sizeof() returns a result of type size_t). I do not know
> whether such systems exist in practice and whether such a system is
> supported by GCC.
>
> The attached patch makes let's the FE emit code of the same data type as
> used in libgfortran - ptrdiff_t for the array indices.
>
> Build and regtested on x86-64-linux.
> OK for the trunk?

Ok, thanks.

Patch

2012-01-13  Tobias Burnus  <burnus@net-b.de>

	PR fortran/51842
	* fortran/trans-types.c (gfc_init_kinds): Use PTRDIFF_TYPE
	instead of a signed int of size POINTER_SIZE for
	gfc_index_integer_kind.

diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index d643c2e..f817a12 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -576,8 +576,8 @@  gfc_init_kinds (void)
   gfc_default_character_kind = gfc_character_kinds[0].kind;
   gfc_character_storage_size = gfc_default_character_kind * 8;
 
-  /* Choose the integer kind the same size as "void*" for our index kind.  */
-  gfc_index_integer_kind = POINTER_SIZE / 8;
+  gfc_index_integer_kind = get_int_kind_from_name (PTRDIFF_TYPE);
+
   /* Pick a kind the same size as the C "int" type.  */
   gfc_c_int_kind = INT_TYPE_SIZE / 8;