From 714996e2c2e1fd788c87b3a87648977468ad4251 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 18 Apr 2019 12:30:36 +0000 Subject: [PATCH] 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 gcc/ * fold-const.c (int_const_binop): Return early on failure. From-SVN: r270443 --- gcc/ChangeLog | 4 ++++ gcc/fold-const.c | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8dba1ed7bf3..5b8c5acb076 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-04-18 Richard Sandiford + + * fold-const.c (int_const_binop): Return early on failure. + 2019-04-18 Richard Sandiford PR middle-end/85164 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 -- 2.30.2