Commit 714996e2 by Richard Sandiford Committed by Richard Sandiford

Fix UB in int_const_binop

When testing PR 85164, the baseline bootstrap-ubsan results had
a lot of failures from int_const_binop.  This is because with the
new overflow handling we can sometimes do:

      poly_res = res;

on an uninitialised res.

2019-04-18  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* fold-const.c (int_const_binop): Return early on failure.

From-SVN: r270443
parent cd7f7c54
2019-04-18 Richard Sandiford <richard.sandiford@arm.com> 2019-04-18 Richard Sandiford <richard.sandiford@arm.com>
* fold-const.c (int_const_binop): Return early on failure.
2019-04-18 Richard Sandiford <richard.sandiford@arm.com>
PR middle-end/85164 PR middle-end/85164
* combine.c (force_int_to_mode): Cast the argument rather than * combine.c (force_int_to_mode): Cast the argument rather than
the result of known_alignment. the result of known_alignment.
......
...@@ -1173,7 +1173,6 @@ tree ...@@ -1173,7 +1173,6 @@ tree
int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2,
int overflowable) int overflowable)
{ {
bool success = false;
poly_wide_int poly_res; poly_wide_int poly_res;
tree type = TREE_TYPE (arg1); tree type = TREE_TYPE (arg1);
signop sign = TYPE_SIGN (type); signop sign = TYPE_SIGN (type);
...@@ -1183,17 +1182,18 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, ...@@ -1183,17 +1182,18 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2,
{ {
wide_int warg1 = wi::to_wide (arg1), res; wide_int warg1 = wi::to_wide (arg1), res;
wide_int warg2 = wi::to_wide (arg2, TYPE_PRECISION (type)); wide_int warg2 = wi::to_wide (arg2, TYPE_PRECISION (type));
success = wide_int_binop (res, code, warg1, warg2, sign, &overflow); if (!wide_int_binop (res, code, warg1, warg2, sign, &overflow))
return NULL_TREE;
poly_res = res; poly_res = res;
} }
else if (poly_int_tree_p (arg1) && poly_int_tree_p (arg2)) else if (!poly_int_tree_p (arg1)
success = poly_int_binop (poly_res, code, arg1, arg2, sign, &overflow); || !poly_int_tree_p (arg2)
if (success) || !poly_int_binop (poly_res, code, arg1, arg2, sign, &overflow))
return force_fit_type (type, poly_res, overflowable, return NULL_TREE;
(((sign == SIGNED || overflowable == -1) return force_fit_type (type, poly_res, overflowable,
&& overflow) (((sign == SIGNED || overflowable == -1)
| TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))); && overflow)
return NULL_TREE; | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)));
} }
/* Return true if binary operation OP distributes over addition in operand /* Return true if binary operation OP distributes over addition in operand
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment