This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]