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] fortran/arith.c -- Fix the range of integers in overflow checks


Friends,

During my recent clean up of arith.[ch], I noticed that 
gfortran computed the integer ranges to check for underflow
and overflow.  For any integer kind, the correct range is

  - huge(i) - 1 <= i <= huge(i)

gfortran was using the range
 
  - huge(i) - 1 <= i <= 2 * huge(i) + 1

The confusion arose because the gfc_integer_info structure
includes a max_int = 2 * huge(i) + 1 member that is used as
a mask in the simplification of the NOT() intrinsic function.

This bugs exists in all versions of gfortran.

The attached patch fixes the problem and problems that where
exposed in the testsuite.  The test program intrinsic_set_exponent.f90
may still fail on 64-bit platforms because in essences it is
a bogus piece of code.  If it fails, please reported it to me
so that I can deleted it.

What does the patch do?  It eliminates the max_int structure
member in gfc_integer_info.  The construction of a mask has
been moved to gfc_simplify_not() and integer range checking is
done within the appropriate interval.

Note, this change has an interesting side effect.  I look
forward to the bogus bug reports for code of the form.

   program HaHa
     integer, parameter :: mini = -2147483648
   end program HaHa

Yes,  -2147483648 is the valid minimum integer(4) value.
However, the above code contains a unary minus expression,
so the integer constant 2147483648 overflows it range.


2006-08-27  Steven G. Kargl  <kargls@comcast.net>

	* gfortran.h (gfc_integer_info): Delete	max_int member
	* arith.c (gfc_arith_init_1): Remove initialization of max_int.
 	(gfc_arith_done_1): Remove clearing of max_int.
 	(gfc_check_integer_range): Use huge instead of max_int.
	* simplify.c (gfc_simplify_not): Build a mask in place of max_int.
 
2006-08-27  Steven G. Kargl  <kargls@comcast.net>

	* gfortran.fortran-torture/execute/intrinsic_set_exponent.f90:
	Comment out illegal code.
 	* gfortran.fortran-torture/compile/data_1.f90: Fix overflow.
	* gfortran.dg/enum_8.f90: Fix dg-error for overflow.
	* gfortran.dg/g77/20030326-1.f: Ditto.

-- 
Steve

Attachment: integer_range.diff
Description: Text document


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