static tree range_binop (enum tree_code, tree, tree, int, tree, int);
static tree range_predecessor (tree);
static tree range_successor (tree);
-static tree make_range (tree, int *, tree *, tree *, bool *);
-static tree build_range_check (tree, tree, int, tree, tree);
-static int merge_ranges (int *, tree *, tree *, int, tree, tree, int, tree,
- tree);
+extern tree make_range (tree, int *, tree *, tree *, bool *);
+extern tree build_range_check (tree, tree, int, tree, tree);
+extern bool merge_ranges (int *, tree *, tree *, int, tree, tree, int,
+ tree, tree);
static tree fold_range_test (enum tree_code, tree, tree, tree);
static tree fold_cond_expr_with_comparison (tree, tree, tree, tree);
static tree unextend (tree, int, int, tree);
case POINTER_TYPE: case REFERENCE_TYPE:
case REAL_TYPE:
case FIXED_POINT_TYPE:
- return build2 (COMPLEX_EXPR, type,
- fold_convert (TREE_TYPE (type), arg),
- fold_convert (TREE_TYPE (type), integer_zero_node));
+ return fold_build2 (COMPLEX_EXPR, type,
+ fold_convert (TREE_TYPE (type), arg),
+ fold_convert (TREE_TYPE (type),
+ integer_zero_node));
case COMPLEX_TYPE:
{
tree rpart, ipart;
because signed overflow is undefined; otherwise, do not change
*STRICT_OVERFLOW_P. */
-static tree
+tree
make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
bool *strict_overflow_p)
{
type, TYPE, return an expression to test if EXP is in (or out of, depending
on IN_P) the range. Return 0 if the test couldn't be created. */
-static tree
+tree
build_range_check (tree type, tree exp, int in_p, tree low, tree high)
{
tree etype = TREE_TYPE (exp), value;
/* Given two ranges, see if we can merge them into one. Return 1 if we
can, 0 if we can't. Set the output range into the specified parameters. */
-static int
+bool
merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
tree high0, int in1_p, tree low1, tree high1)
{
if (TREE_TYPE (t) != ptrtype)
t = build1 (NOP_EXPR, ptrtype, t);
}
+ else if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
+ {
+ t = build_fold_addr_expr (TREE_OPERAND (t, 0));
+
+ if (TREE_TYPE (t) != ptrtype)
+ t = fold_convert (ptrtype, t);
+ }
else
t = build1 (ADDR_EXPR, ptrtype, t);
&& TREE_INT_CST_HIGH (tree11) == 0
&& ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
- return build2 (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
- code0 == LSHIFT_EXPR ? tree01 : tree11);
+ return fold_convert (type,
+ build2 (LROTATE_EXPR,
+ TREE_TYPE (TREE_OPERAND (arg0, 0)),
+ TREE_OPERAND (arg0, 0),
+ code0 == LSHIFT_EXPR
+ ? tree01 : tree11));
else if (code11 == MINUS_EXPR)
{
tree tree110, tree111;
(TREE_TYPE (TREE_OPERAND
(arg0, 0))))
&& operand_equal_p (tree01, tree111, 0))
- return build2 ((code0 == LSHIFT_EXPR
- ? LROTATE_EXPR
- : RROTATE_EXPR),
- type, TREE_OPERAND (arg0, 0), tree01);
+ return fold_convert (type,
+ build2 ((code0 == LSHIFT_EXPR
+ ? LROTATE_EXPR
+ : RROTATE_EXPR),
+ TREE_TYPE (TREE_OPERAND (arg0, 0)),
+ TREE_OPERAND (arg0, 0), tree01));
}
else if (code01 == MINUS_EXPR)
{
(TREE_TYPE (TREE_OPERAND
(arg0, 0))))
&& operand_equal_p (tree11, tree011, 0))
- return build2 ((code0 != LSHIFT_EXPR
- ? LROTATE_EXPR
- : RROTATE_EXPR),
- type, TREE_OPERAND (arg0, 0), tree11);
+ return fold_convert (type,
+ build2 ((code0 != LSHIFT_EXPR
+ ? LROTATE_EXPR
+ : RROTATE_EXPR),
+ TREE_TYPE (TREE_OPERAND (arg0, 0)),
+ TREE_OPERAND (arg0, 0), tree11));
}
}
}
if (prec < HOST_BITS_PER_WIDE_INT
|| newmask == ~(unsigned HOST_WIDE_INT) 0)
{
+ tree newmaskt;
+
if (shift_type != TREE_TYPE (arg0))
{
tem = fold_build2 (TREE_CODE (arg0), shift_type,
}
else
tem = op0;
- return fold_build2 (BIT_AND_EXPR, type, tem,
- build_int_cst_type (TREE_TYPE (op1),
- newmask));
+ newmaskt = build_int_cst_type (TREE_TYPE (op1), newmask);
+ if (!tree_int_cst_equal (newmaskt, arg1))
+ return fold_build2 (BIT_AND_EXPR, type, tem, newmaskt);
}
}
}