summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-04-18 12:30:36 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-04-18 12:30:36 +0000
commit714996e2c2e1fd788c87b3a87648977468ad4251 (patch)
treebe03f26d6f967997c007886d0080a9d364a3f1e2 /gcc/fold-const.c
parentcd7f7c54a43c435152b2ac76b6e74ae6a3430472 (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.c20
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