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
2012-01-13  Tobias Burnus  <bur...@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;
 

Reply via email to