+2003-12-31 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/12632
+ * tree.c (integer_nonzerop): New predicate for nonzero integers.
+ * tree.h (integer_nonzerop): Add function prototype.
+ * fold-const.c (fold) <COND_EXPR>: 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 <kazu@cs.umass.edu>
Backport from mainline:
+2003-12-31 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-05 Toon Moene <toon@moene.indiv.nluug.nl>
PR fortran/12633
\f
/* 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));
}
}
+ /* If the array index is safe at compile-time, return element. */
+ if (integer_nonzerop (cond))
+ return element;
+
{
int len;
char *proc;
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.
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;
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;
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);
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);
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);
/* 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
+2003-12-31 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/12632
+ * g77.dg/12632.f: New test case.
+
2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
PR c++/13445
|| (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. */
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. */