diff options
author | Roger Sayle <roger@eyesopen.com> | 2003-12-29 16:16:39 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2003-12-29 16:16:39 +0000 |
commit | b66906a8ff79931bc3d23b9362833b1567c5ac56 (patch) | |
tree | 8cc330d809fbbe70f50065f881b684ae3503d29c /gcc/f | |
parent | 68deab91f26e8a5266a8bd9086bbf5129c619c03 (diff) | |
download | gcc-b66906a8ff79931bc3d23b9362833b1567c5ac56.zip gcc-b66906a8ff79931bc3d23b9362833b1567c5ac56.tar.gz gcc-b66906a8ff79931bc3d23b9362833b1567c5ac56.tar.bz2 |
re PR fortran/12632 ([g77 only] -fbounds-check ICE)
PR fortran/12632
* fold-const.c (fold) <COND_EXPR>: Don't fold a constant condition,
if the type of the selected branch doesn't match its' parent.
* com.c (ffecom_subscript_check_): Take as an extra argument the
(possibly NULL) decl of the array. Don't create unnecessary tree
nodes if the array index is known to be safe at compile-time.
If the array index is unsafe, force the array decl into memory to
avoid RTL expansion problems.
(ffecom_array_ref_): Update calls to ffecom_subscript_check_.
(ffecom_char_args_x_): Likewise.
* g77.dg/12632.f: New test case.
From-SVN: r75203
Diffstat (limited to 'gcc/f')
-rw-r--r-- | gcc/f/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/f/com.c | 28 |
2 files changed, 26 insertions, 13 deletions
diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog index 99a666f..3dcc5628 100644 --- a/gcc/f/ChangeLog +++ b/gcc/f/ChangeLog @@ -1,3 +1,14 @@ +2003-12-29 Roger Sayle <roger@eyesopen.com> + + PR fortran/12632 + * com.c (ffecom_subscript_check_): Take as an extra argument the + (possibly NULL) decl of the array. Don't create unnecessary tree + nodes if the array index is known to be safe at compile-time. + If the array index is unsafe, force the array decl into memory to + avoid RTL expansion problems. + (ffecom_array_ref_): Update calls to ffecom_subscript_check_. + (ffecom_char_args_x_): Likewise. + 2003-12-06 Kelley Cook <kcook@gcc.gnu.org> * Make-lang.in (G77_CROSS_NAME): Delete. diff --git a/gcc/f/com.c b/gcc/f/com.c index 535ddbb..a64ef86 100644 --- a/gcc/f/com.c +++ b/gcc/f/com.c @@ -638,15 +638,16 @@ static GTY(()) tree shadowed_labels; /* Return the subscript expression, modified to do range-checking. - `array' is the array to be checked against. + `array' is the array type to be checked against. `element' is the subscript expression to check. `dim' is the dimension number (starting at 0). `total_dims' is the total number of dimensions (0 for CHARACTER substring). + `item' is the array decl or NULL_TREE. */ static tree ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims, - const char *array_name) + const char *array_name, tree item) { tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array)); tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array)); @@ -713,6 +714,10 @@ ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims, } } + /* If the array index is safe at compile-time, return element. */ + if (integer_nonzerop (cond)) + return element; + { int len; char *proc; @@ -807,13 +812,10 @@ ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims, TREE_SIDE_EFFECTS (die) = 1; die = convert (void_type_node, die); - element = ffecom_3 (COND_EXPR, - TREE_TYPE (element), - cond, - element, - die); + if (integer_zerop (cond) && item) + ffe_mark_addressable (item); - return element; + return ffecom_3 (COND_EXPR, TREE_TYPE (element), cond, element, die); } /* Return the computed element of an array reference. @@ -899,7 +901,7 @@ ffecom_arrayref_ (tree item, ffebld expr, int want_ptr) element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE); if (flag_bounds_check) element = ffecom_subscript_check_ (array, element, i, total_dims, - array_name); + array_name, item); if (element == error_mark_node) return element; @@ -945,7 +947,7 @@ ffecom_arrayref_ (tree item, ffebld expr, int want_ptr) element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE); if (flag_bounds_check) element = ffecom_subscript_check_ (array, element, i, total_dims, - array_name); + array_name, item); if (element == error_mark_node) return element; @@ -2037,7 +2039,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null) end_tree = ffecom_expr (end); if (flag_bounds_check) end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0, - char_name); + char_name, NULL_TREE); end_tree = convert (ffecom_f2c_ftnlen_type_node, end_tree); @@ -2055,7 +2057,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null) start_tree = ffecom_expr (start); if (flag_bounds_check) start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0, - char_name); + char_name, NULL_TREE); start_tree = convert (ffecom_f2c_ftnlen_type_node, start_tree); @@ -2088,7 +2090,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null) end_tree = ffecom_expr (end); if (flag_bounds_check) end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0, - char_name); + char_name, NULL_TREE); end_tree = convert (ffecom_f2c_ftnlen_type_node, end_tree); |