This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, Fortran, committed] Fix Fortran bug affecting MinGW-w64, only
- From: Tobias Burnus <burnus at net-b dot de>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, gfortran <fortran at gcc dot gnu dot org>
- Date: Sat, 12 Jul 2014 21:15:02 +0200
- Subject: [Patch, Fortran, committed] Fix Fortran bug affecting MinGW-w64, only
- Authentication-results: sourceware.org; auth=none
64bit Windows is special as "long" is only 32bit wide - while pointers
are 64bit and, hence, wider.
Another special code is gfortran's array descriptor. Its "dtype" field
is of type ptrdiff_t and it stores the array rank and type in the first
6 bits and uses the remaining size to store the byte size for an array.
In case of 32bit systems, one has 32bits - 6 bits = 24 bits (or
There seems to be a single piece of code in gfortran, which assumes that
a pointer and long have the same width. Namely, the code which checks
that one can squeeze the array-element size together with the data type
and the rank into the "dtype" field of the array descriptor, which has
the type ptrdiff_t.
For a system with 32bit pointer size (= type precision of size_type_node
or for ptrdiff_t), one has 32 bits minus 6 bits = 26 bits space. Thus, a
single array element might "only" be 64 mega bytes large. For 64bit
pointers, 58 bits remain.
For some odd reason, the code does not use size_type_node or something
equivalent but it uses an unsigned long. On 32bit Windows and on Linux,
everything is fine. But on 64bit Windows (i.e. MinGW-w64), one tries to
squeeze 58 bits into a 32bit pointer â which will cause that
gfc_max_array_element_size has the wrong result.
This patch does the obvious: It masks out the required bits on a
size_type_node instead.
Committed as obvious as Rev. 212485.
* * *
Unfortunately, that patch does not solve the original problem: On 32bit
â and now also on 64 bit â Windows, the array and the trailing "done" is
not printed. One has still to investigate why that fails.
Tobias
Index: gcc/fortran/ChangeLog
===================================================================
--- gcc/fortran/ChangeLog (Revision 212484)
+++ gcc/fortran/ChangeLog (Arbeitskopie)
@@ -1,5 +1,11 @@
2014-07-12 Tobias Burnus <burnus@net-b.de>
+ PR fortran/61628
+ * trans-types.c (gfc_init_types): Fix data-type bug
+ with gfc_max_array_element_size.
+
+2014-07-12 Tobias Burnus <burnus@net-b.de>
+
* libgfortran.h (libcaf_atomic_codes): Add.
* trans-decl.c (gfor_fndecl_caf_atomic_def,
gfor_fndecl_caf_atomic_ref, gfor_fndecl_caf_atomic_cas,
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c (Revision 212483)
+++ gcc/fortran/trans-types.c (Arbeitskopie)
@@ -955,9 +955,9 @@ gfc_init_types (void)
n = TYPE_PRECISION (gfc_array_index_type) - GFC_DTYPE_SIZE_SHIFT;
gfc_max_array_element_size
- = wide_int_to_tree (long_unsigned_type_node,
+ = wide_int_to_tree (size_type_node,
wi::mask (n, UNSIGNED,
- TYPE_PRECISION (long_unsigned_type_node)));
+ TYPE_PRECISION (size_type_node)));
boolean_type_node = gfc_get_logical_type (gfc_default_logical_kind);
boolean_true_node = build_int_cst (boolean_type_node, 1);