This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[PATCH] New option to support asymmetric integer ranges in gfortran
- From: Scott Robert Ladd <coyote at coyotegulch dot com>
- To: fortran at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Fri, 26 Dec 2003 13:41:29 -0500
- Subject: [PATCH] New option to support asymmetric integer ranges in gfortran
Purpose:
Section 13.7.1 of ISO/IEC 1539-1 ("Fortran 95") specifies that integers
be symmetrical around zero. For example, in terms of an 8-bit integer,
Fortran 95 requires integer values to be in the range [-127,+127]. Two's
complement representation, used on the majority of GCC-supported
platforms, supports the asymmetrical range [-128,+127].
Other programming languages and Fortran 95 compilers support the minimum
allowed by two's complement representation; this could result in
incompatibility between gfortran-generated code and values produced by
other languages or compilers.
The following patch allows gfortran to ignore the limits of 13.7.1 for
the purpose of accepting two's complement minimum values.
Tested on ia32 (P3 and P4); my ancient ultrasparc is still compiling the
compiler.
Example:
The following program only compiles and runs with use of the
-fasymmetric-integers flag (implemented by this patch):
program parambug
implicit none
integer, parameter :: MY_KIND = SELECTED_INT_KIND(9)
integer(MY_KIND), parameter :: X = -2147483648_MY_KIND
write (*,*) X,",",MY_KIND
end program parambug
When compiled with gfortran and -fasymmetric-integers, the program
produces the output:
-2147483648 , 4
The above result matches the output of the program when it is compiled
with Lahey Fortran 95 6.1 and Intel Fortran 95 8.0.
Note:
Being something of a neophyte at patching GCC, I hope the following is
correct and complete. Please be gentle... ;)
ChangeLog:
2003-12-25 Scott Robert Ladd <coyote@coyotegulch.com>
PR c++/13070
* gcc/fortran/gfortran.h: Added flag_asymmetric_integers
to gfc_option_t
* gcc/fortran/options.c (gfc_init_options): Initialized
flag_asymmetric_integers to 0 (false)
* gcc/fortran/options.c (gfc_handle_option): Added section
for setting flag_asymmetric_integers
* gcc/fortran/arith.c (gfc_arith_init_1): When
-fasymmetric_integers is set, subtract 1 from minimum
limit to reflect realities of two's complement signed
integers.
* gcc/fortran/lang.opt: Added entry for -fasymmetric_integers
Patches:
*** gcc/gcc/fortran-original/gfortran.h 2003-12-26 11:08:02.000000000 -0500
--- gcc/gcc/fortran/gfortran.h 2003-12-26 11:10:14.000000000 -0500
*************** typedef struct
*** 1224,1229 ****
--- 1224,1230 ----
int flag_no_backend;
int flag_pack_derived;
int flag_repack_arrays;
+ int flag_asymmetric_integers;
int q_kind;
int r8;
*** gcc/gcc/fortran-original/options.c 2003-12-26 11:08:02.000000000 -0500
--- gcc/gcc/fortran/options.c 2003-12-26 12:06:46.000000000 -0500
*************** gfc_init_options (unsigned int argc ATTR
*** 67,72 ****
--- 67,73 ----
gfc_option.flag_no_backend = 0;
gfc_option.flag_pack_derived = 0;
gfc_option.flag_repack_arrays = 0;
+ gfc_option.flag_asymmetric_integers = 0;
gfc_option.q_kind = gfc_default_double_kind ();
gfc_option.i8 = 0;
*************** gfc_handle_option (size_t scode, const c
*** 253,258 ****
--- 254,263 ----
gfc_option.flag_repack_arrays = value;
break;
+ case OPT_fasymmetric_integers:
+ gfc_option.flag_asymmetric_integers = value;
+ break;
+
case OPT_ffixed_line_length_80:
gfc_option.fixed_line_length = 80;
break;
*** gcc/gcc/fortran-original/arith.c 2003-12-26 11:08:02.000000000 -0500
--- gcc/gcc/fortran/arith.c 2003-12-26 11:24:06.000000000 -0500
*************** gfc_arith_init_1 (void)
*** 697,708 ****
/* These are the numbers that are actually representable by the
target. For bases other than two, this needs to be changed. */
if (int_info->radix != 2)
! gfc_internal_error ("Fix min_int, max_int calculation");
mpz_init (int_info->min_int);
mpz_neg (int_info->min_int, int_info->huge);
! /* No -1 here, because the representation is symmetric. */
!
mpz_init (int_info->max_int);
mpz_add (int_info->max_int, int_info->huge, int_info->huge);
mpz_add_ui (int_info->max_int, int_info->max_int, 1);
--- 697,716 ----
/* These are the numbers that are actually representable by the
target. For bases other than two, this needs to be changed. */
if (int_info->radix != 2)
! gfc_internal_error ("Fix min_int, max_int calculation");
mpz_init (int_info->min_int);
mpz_neg (int_info->min_int, int_info->huge);
!
! /* On systems with two's complement integers, the min value is
! outside the range of the symmetric integers required by ISO
! 1539-1 (13.7.1 in F95, 13.4 in F0x). Other compilers and
! languages accept the min two's complement value, so the
! -fasymmetric-integers switch allows gfortran to violate the
! standard in the name of compatibility. */
! if (gfc_option.flag_asymmetric_integers)
! mpz_sub_ui (int_info->min_int, int_info->min_int, 1);
!
mpz_init (int_info->max_int);
mpz_add (int_info->max_int, int_info->huge, int_info->huge);
mpz_add_ui (int_info->max_int, int_info->max_int, 1);
*** gcc/gcc/fortran-original/lang.opt 2003-12-26 11:08:02.000000000 -0500
--- gcc/gcc/fortran/lang.opt 2003-12-26 12:13:52.000000000 -0500
*************** frepack-arrays
*** 125,130 ****
--- 125,134 ----
F95
Copy array sections into a contiguous block on procedure entry
+ fasymmetric-integers
+ F95
+ Accept minimum negative integer values outside the range specified by
the Standard
+
i8
F95 RejectNegative
Set the default integer kind to double precision
--
Scott Robert Ladd
Coyote Gulch Productions (http://www.coyotegulch.com)
Software Invention for High-Performance Computing