diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-04-18 12:30:36 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-04-18 12:30:36 +0000 |
commit | 714996e2c2e1fd788c87b3a87648977468ad4251 (patch) | |
tree | be03f26d6f967997c007886d0080a9d364a3f1e2 /gcc/fold-const.c | |
parent | cd7f7c54a43c435152b2ac76b6e74ae6a3430472 (diff) |
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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c2884a67519..c4257721cfe 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1173,7 +1173,6 @@ tree int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int overflowable) { - bool success = false; poly_wide_int poly_res; tree type = TREE_TYPE (arg1); signop sign = TYPE_SIGN (type); @@ -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 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; } - else if (poly_int_tree_p (arg1) && poly_int_tree_p (arg2)) - success = poly_int_binop (poly_res, code, arg1, arg2, sign, &overflow); - if (success) - return force_fit_type (type, poly_res, overflowable, - (((sign == SIGNED || overflowable == -1) - && overflow) - | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))); - return NULL_TREE; + else if (!poly_int_tree_p (arg1) + || !poly_int_tree_p (arg2) + || !poly_int_binop (poly_res, code, arg1, arg2, sign, &overflow)) + return NULL_TREE; + return force_fit_type (type, poly_res, overflowable, + (((sign == SIGNED || overflowable == -1) + && overflow) + | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))); } /* Return true if binary operation OP distributes over addition in operand |