This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[patch, fortran] PR36515 Integer read value overflow for a invalid integer.
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- To: Fortran List <fortran at gcc dot gnu dot org>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 13 Jun 2008 22:54:56 -0700
- Subject: [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