From: Roger Sayle Date: Thu, 1 Jan 2004 04:44:59 +0000 (+0000) Subject: re PR fortran/12632 ([g77 only] -fbounds-check ICE) X-Git-Tag: releases/gcc-3.3.3~133 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ecbe3a426c7221ab24ded7cea629597cd4a081a;p=thirdparty%2Fgcc.git re PR fortran/12632 ([g77 only] -fbounds-check ICE) PR fortran/12632 * tree.c (integer_nonzerop): New predicate for nonzero integers. * tree.h (integer_nonzerop): Add function prototype. * fold-const.c (fold) : Don't fold a constant condition, if we'd replace a COND_EXPR of non-void type by one of its operands of void type. * 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: r75295 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10c31ad4ffe8..e569f4d122c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2003-12-31 Roger Sayle + + PR fortran/12632 + * tree.c (integer_nonzerop): New predicate for nonzero integers. + * tree.h (integer_nonzerop): Add function prototype. + * fold-const.c (fold) : Don't fold a constant condition, + if we'd replace a COND_EXPR of non-void type by one of its operands + of void type. + 2003-12-31 Kazu Hirata Backport from mainline: diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog index cd6f75df136f..2049f2aad355 100644 --- a/gcc/f/ChangeLog +++ b/gcc/f/ChangeLog @@ -1,3 +1,14 @@ +2003-12-31 Roger Sayle + + 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-05 Toon Moene PR fortran/12633 diff --git a/gcc/f/com.c b/gcc/f/com.c index fca0f94ac9d6..14445cdd13eb 100644 --- a/gcc/f/com.c +++ b/gcc/f/com.c @@ -639,15 +639,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)); @@ -714,6 +715,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; @@ -808,13 +813,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. @@ -900,7 +902,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; @@ -946,7 +948,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; @@ -2045,7 +2047,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); @@ -2063,7 +2065,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); @@ -2096,7 +2098,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); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 94682d477ee4..bf3c1fa93be1 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6785,9 +6785,17 @@ fold (expr) /* Pedantic ANSI C says that a conditional expression is never an lvalue, so all simple results must be passed through pedantic_non_lvalue. */ if (TREE_CODE (arg0) == INTEGER_CST) - return pedantic_non_lvalue - (TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1))); - else if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0)) + { + tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1)); + /* Only optimize constant conditions when the selected branch + has the same type as the COND_EXPR. This avoids optimizing + away "c ? x : throw", where the throw has a void type. */ + if (! VOID_TYPE_P (TREE_TYPE (tem)) + || VOID_TYPE_P (TREE_TYPE (t))) + return pedantic_non_lvalue (tem); + return t; + } + if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0)) return pedantic_omit_one_operand (type, arg1, arg0); /* If the second operand is zero, invert the comparison and swap diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 52217a05f72c..3b58c492f1d9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-12-31 Roger Sayle + + PR fortran/12632 + * g77.dg/12632.f: New test case. + 2003-12-29 Nathan Sidwell PR c++/13445 diff --git a/gcc/tree.c b/gcc/tree.c index e8c2541c1d99..0ecde79d4e0a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -723,6 +723,23 @@ integer_pow2p (expr) || (low == 0 && (high & (high - 1)) == 0)); } +/* Return 1 if EXPR is an integer constant other than zero or a + complex constant other than zero. */ + +int +integer_nonzerop (tree expr) +{ + STRIP_NOPS (expr); + + return ((TREE_CODE (expr) == INTEGER_CST + && ! TREE_CONSTANT_OVERFLOW (expr) + && (TREE_INT_CST_LOW (expr) != 0 + || TREE_INT_CST_HIGH (expr) != 0)) + || (TREE_CODE (expr) == COMPLEX_CST + && (integer_nonzerop (TREE_REALPART (expr)) + || integer_nonzerop (TREE_IMAGPART (expr))))); +} + /* Return the power of two represented by a tree node known to be a power of two. */ diff --git a/gcc/tree.h b/gcc/tree.h index 1ad4b142c78a..275511f83881 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2637,6 +2637,11 @@ extern int integer_all_onesp PARAMS ((tree)); extern int integer_pow2p PARAMS ((tree)); +/* integer_nonzerop (tree x) is nonzero if X is an integer constant + with a nonzero value. */ + +extern int integer_nonzerop (tree); + /* staticp (tree x) is nonzero if X is a reference to data allocated at a fixed address in memory. */