if (fold_deferred_overflow_warning != NULL
&& code != 0
&& code < (int) fold_deferred_overflow_code)
- fold_deferred_overflow_code = code;
+ fold_deferred_overflow_code = (enum warn_strict_overflow_code) code;
return;
}
bool honor_nans = HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg)));
enum comparison_code lcompcode = comparison_to_compcode (lcode);
enum comparison_code rcompcode = comparison_to_compcode (rcode);
- enum comparison_code compcode;
+ int compcode;
switch (code)
{
else if (compcode == COMPCODE_FALSE)
return constant_boolean_node (false, truth_type);
else
- return fold_build2 (compcode_to_comparison (compcode),
- truth_type, ll_arg, lr_arg);
+ {
+ enum tree_code tcode;
+
+ tcode = compcode_to_comparison ((enum comparison_code) compcode);
+ return fold_build2 (tcode, truth_type, ll_arg, lr_arg);
+ }
}
\f
/* Return nonzero if two operands (typically of the same tree node)
tree
fold_truth_not_expr (tree arg)
{
- tree type = TREE_TYPE (arg);
+ tree t, type = TREE_TYPE (arg);
enum tree_code code = TREE_CODE (arg);
/* If this is a comparison, we can simply invert it, except for
&& code != ORDERED_EXPR && code != UNORDERED_EXPR
&& code != NE_EXPR && code != EQ_EXPR)
return NULL_TREE;
- else
- {
- code = invert_tree_comparison (code,
- HONOR_NANS (TYPE_MODE (op_type)));
- if (code == ERROR_MARK)
- return NULL_TREE;
- else
- return build2 (code, type,
- TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
- }
+
+ code = invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (op_type)));
+ if (code == ERROR_MARK)
+ return NULL_TREE;
+
+ t = build2 (code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
+ if (EXPR_HAS_LOCATION (arg))
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (arg));
+ return t;
}
switch (code)
return constant_boolean_node (integer_zerop (arg), type);
case TRUTH_AND_EXPR:
- return build2 (TRUTH_OR_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_OR_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_OR_EXPR:
- return build2 (TRUTH_AND_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_AND_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_XOR_EXPR:
/* Here we can invert either operand. We invert the first operand
negation of the second operand. */
if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
- return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
- TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
+ t = build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
+ TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
else
- return build2 (TRUTH_XOR_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- TREE_OPERAND (arg, 1));
+ t = build2 (TRUTH_XOR_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ TREE_OPERAND (arg, 1));
+ break;
case TRUTH_ANDIF_EXPR:
- return build2 (TRUTH_ORIF_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_ORIF_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_ORIF_EXPR:
- return build2 (TRUTH_ANDIF_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (TRUTH_ANDIF_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case TRUTH_NOT_EXPR:
return TREE_OPERAND (arg, 0);
/* A COND_EXPR may have a throw as one operand, which
then has void type. Just leave void operands
as they are. */
- return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
- VOID_TYPE_P (TREE_TYPE (arg1))
- ? arg1 : invert_truthvalue (arg1),
- VOID_TYPE_P (TREE_TYPE (arg2))
- ? arg2 : invert_truthvalue (arg2));
+ t = build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
+ VOID_TYPE_P (TREE_TYPE (arg1))
+ ? arg1 : invert_truthvalue (arg1),
+ VOID_TYPE_P (TREE_TYPE (arg2))
+ ? arg2 : invert_truthvalue (arg2));
+ break;
}
case COMPOUND_EXPR:
- return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
- invert_truthvalue (TREE_OPERAND (arg, 1)));
+ t = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
+ invert_truthvalue (TREE_OPERAND (arg, 1)));
+ break;
case NON_LVALUE_EXPR:
return invert_truthvalue (TREE_OPERAND (arg, 0));
case NOP_EXPR:
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
- return build1 (TRUTH_NOT_EXPR, type, arg);
+ {
+ t = build1 (TRUTH_NOT_EXPR, type, arg);
+ break;
+ }
+
+ /* ... fall through ... */
case CONVERT_EXPR:
case FLOAT_EXPR:
- return build1 (TREE_CODE (arg), type,
- invert_truthvalue (TREE_OPERAND (arg, 0)));
+ t = build1 (TREE_CODE (arg), type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)));
+ break;
case BIT_AND_EXPR:
if (!integer_onep (TREE_OPERAND (arg, 1)))
- break;
- return build2 (EQ_EXPR, type, arg,
- build_int_cst (type, 0));
+ return NULL_TREE;
+ t = build2 (EQ_EXPR, type, arg, build_int_cst (type, 0));
+ break;
case SAVE_EXPR:
- return build1 (TRUTH_NOT_EXPR, type, arg);
+ t = build1 (TRUTH_NOT_EXPR, type, arg);
+ break;
case CLEANUP_POINT_EXPR:
- return build1 (CLEANUP_POINT_EXPR, type,
- invert_truthvalue (TREE_OPERAND (arg, 0)));
+ t = build1 (CLEANUP_POINT_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)));
+ break;
default:
+ t = NULL_TREE;
break;
}
- return NULL_TREE;
+ if (t && EXPR_HAS_LOCATION (arg))
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (arg));
+
+ return t;
}
/* Return a simplified tree node for the truth-negation of ARG. This
break;
case GT_EXPR:
- /* If C1 is C2 - 1, this is max(A, C2). */
+ /* If C1 is C2 - 1, this is max(A, C2), but use ARG00's type for
+ MAX_EXPR, to preserve the signedness of the comparison. */
if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
OEP_ONLY_CONST)
&& operand_equal_p (arg01,
const_binop (MINUS_EXPR, arg2,
build_int_cst (type, 1), 0),
OEP_ONLY_CONST))
- return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
- type,
- fold_convert (type, arg1),
- arg2));
+ return pedantic_non_lvalue (fold_convert (type,
+ fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
+ arg00,
+ fold_convert (TREE_TYPE (arg00),
+ arg2))));
break;
case GE_EXPR:
- /* If C1 is C2 + 1, this is max(A, C2). */
+ /* If C1 is C2 + 1, this is max(A, C2), with the same care as above. */
if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
OEP_ONLY_CONST)
&& operand_equal_p (arg01,
const_binop (PLUS_EXPR, arg2,
build_int_cst (type, 1), 0),
OEP_ONLY_CONST))
- return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
- type,
- fold_convert (type, arg1),
- arg2));
+ return pedantic_non_lvalue (fold_convert (type,
+ fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
+ arg00,
+ fold_convert (TREE_TYPE (arg00),
+ arg2))));
break;
case NE_EXPR:
break;
}
}
- if (flag_unsafe_math_optimizations
+ if (flag_unsafe_math_optimizations
&& (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
&& (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
&& (tem = distribute_real_division (code, type, arg0, arg1)))
}
}
- if (flag_unsafe_math_optimizations
+ if (FLOAT_TYPE_P (type)
+ && flag_unsafe_math_optimizations
&& (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
&& (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
&& (tem = distribute_real_division (code, type, arg0, arg1)))
if (code == LROTATE_EXPR || code == RROTATE_EXPR)
low = low % TYPE_PRECISION (type);
else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
- return build_int_cst (type, 0);
+ return omit_one_operand (type, build_int_cst (type, 0),
+ TREE_OPERAND (arg0, 0));
else
low = TYPE_PRECISION (type) - 1;
}