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] PR36515 Integer read value overflow for a invalid integer.


Hi folks,

To provide legacy compatibility with g77, this patch enables -fno-range-check at runtime. This is done by adding the range-check flag to the compile options array generated in trans-decl.c. The flag is then used in read.c to ignore the overflow.

Regression tested on x86-64 and new test case provided.

OK for Trunk. Thanks Steve Kargl for pointing out the place in read.c

Jerry

2008-06-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR fortran/36515
	* trans-decl.c (gfc_generate_function_code): Add range_check to options
	array.

2008-06-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR fortran/36515
	* libgfortran.h (compile_options_t): Add int range_check to structure.
	* runtime/compile_options.c (set_options): Add range_check option.
	(init_compile_options): Likewise.
	*io/read.c (read_decimal): Change overflow checks to include
	range_check.
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c	(revision 136759)
+++ gcc/fortran/trans-decl.c	(working copy)
@@ -3292,9 +3292,13 @@ gfc_generate_function_code (gfc_namespac
 			 build_int_cst (integer_type_node,
 					flag_bounds_check), array);
 
+      array = tree_cons (NULL_TREE,
+			 build_int_cst (integer_type_node,
+					gfc_option.flag_range_check), array);
+
       array_type = build_array_type (integer_type_node,
 				     build_index_type (build_int_cst (NULL_TREE,
-								      6)));
+								      7)));
       array = build_constructor_from_list (array_type, nreverse (array));
       TREE_CONSTANT (array) = 1;
       TREE_STATIC (array) = 1;
@@ -3308,7 +3312,7 @@ gfc_generate_function_code (gfc_namespac
       var = gfc_build_addr_expr (pvoid_type_node, var);
 
       tmp = build_call_expr (gfor_fndecl_set_options, 2,
-			     build_int_cst (integer_type_node, 7), var);
+			     build_int_cst (integer_type_node, 8), var);
       gfc_add_expr_to_block (&body, tmp);
     }
 
Index: libgfortran/runtime/compile_options.c
===================================================================
--- libgfortran/runtime/compile_options.c	(revision 136759)
+++ libgfortran/runtime/compile_options.c	(working copy)
@@ -105,6 +105,8 @@ set_options (int num, int options[])
     compile_options.sign_zero = options[5];
   if (num >= 7)
     compile_options.bounds_check = options[6];
+  if (num >= 8)
+    compile_options.range_check = options[7];
 
   /* If backtrace is required, we set signal handlers on most common
      signals.  */
@@ -146,6 +148,7 @@ init_compile_options (void)
   compile_options.dump_core = 0;
   compile_options.backtrace = 0;
   compile_options.sign_zero = 1;
+  compile_options.range_check = 1;
 }
 
 /* Function called by the front-end to tell us the
Index: libgfortran/libgfortran.h
===================================================================
--- libgfortran/libgfortran.h	(revision 136763)
+++ libgfortran/libgfortran.h	(working copy)
@@ -477,6 +477,7 @@ typedef struct
   size_t record_marker;
   int max_subrecord_length;
   int bounds_check;
+  int range_check;
 }
 compile_options_t;
 
Index: libgfortran/io/read.c
===================================================================
--- libgfortran/io/read.c	(revision 136763)
+++ libgfortran/io/read.c	(working copy)
@@ -428,13 +428,13 @@ read_decimal (st_parameter_dt *dtp, cons
       if (c < '0' || c > '9')
 	goto bad;
 
-      if (value > maxv_10)
+      if (value > maxv_10 && compile_options.range_check == 1)
 	goto overflow;
 
       c -= '0';
       value = 10 * value;
 
-      if (value > maxv - c)
+      if (value > maxv - c && compile_options.range_check == 1)
 	goto overflow;
       value += c;
     }
! { dg-do run }
! { dg-options "-fno-range-check" }
! PR36515 Integer read a value overflow for an invalid integer.
! This tests that -fno-range-check allows this legacy behavior at runtime.
program int_range
character(25) :: inputline = "-2147483648"
integer*4 smallest
read(inputline,100) smallest
100 format(1i11)
if (smallest.ne.-2147483648) call abort
end

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