diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-10-02 09:45:40 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-10-02 09:45:40 +0000 |
commit | a1488398d4abf50ff8b2ec25d6a75185aefc52c8 (patch) | |
tree | e5cca47aca114b176833f91da6a74b6829051ce5 | |
parent | 1a6da556c414bbbec6df82fdb342e8b84e205507 (diff) | |
download | gcc-a1488398d4abf50ff8b2ec25d6a75185aefc52c8.zip gcc-a1488398d4abf50ff8b2ec25d6a75185aefc52c8.tar.gz gcc-a1488398d4abf50ff8b2ec25d6a75185aefc52c8.tar.bz2 |
Fix mismatched precisions in tree arithmetic
The tree wi:: decompose routine wasn't asserting that the requested
precision matched the tree's precision. This could make a difference
for unsigned trees that are exactly N HWIs wide and that have the upper
bit set, since we then need an extra zero HWI when extending it to wider
precisions (as for wi::to_widest).
This patch adds the assert and fixes the fallout shown by the testsuite.
Go seems to be unaffected.
2017-10-02 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
* tree.h (wi::int_traits <const_tree>::decompose): Assert that the
requested precision matches the type's.
* calls.c (alloc_max_size): Calculate the new candidate size as
a widest_int and use wi::to_widest when comparing it with the
current candidate size.
* gimple-ssa-warn-alloca.c (pass_walloca::execute): Compare with
zero rather than integer_zero_node.
* match.pd: Check for a no-op conversion before using wi::add
rather than after. Use tree_to_uhwi when summing small shift
counts into an unsigned int.
gcc/c-family/
* c-warn.c (warn_tautological_bitwise_comparison): Use wi::to_widest
when combining the original unconverted comparison operands.
gcc/cp/
* constexpr.c (cxx_eval_store_expression): Use wi::to_widest
when comparing the array bounds with an ARRAY_REF index.
gcc/ada/
* gcc-interface/decl.c (annotate_value): Use wi::to_widest when
handling the form (plus/mult (convert @0) @1).
From-SVN: r253341
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/ada/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 8 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-family/c-warn.c | 10 | ||||
-rw-r--r-- | gcc/calls.c | 5 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 2 | ||||
-rw-r--r-- | gcc/gimple-ssa-warn-alloca.c | 4 | ||||
-rw-r--r-- | gcc/match.pd | 7 | ||||
-rw-r--r-- | gcc/tree.h | 1 |
11 files changed, 49 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4515802..822afa0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,17 @@ 2017-10-02 Richard Sandiford <richard.sandiford@linaro.org> + + * tree.h (wi::int_traits <const_tree>::decompose): Assert that the + requested precision matches the type's. + * calls.c (alloc_max_size): Calculate the new candidate size as + a widest_int and use wi::to_widest when comparing it with the + current candidate size. + * gimple-ssa-warn-alloca.c (pass_walloca::execute): Compare with + zero rather than integer_zero_node. + * match.pd: Check for a no-op conversion before using wi::add + rather than after. Use tree_to_uhwi when summing small shift + counts into an unsigned int. + +2017-10-02 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 4e931f9..848b88f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2017-10-02 Richard Sandiford <richard.sandiford@linaro.org> + + * gcc-interface/decl.c (annotate_value): Use wi::to_widest when + handling the form (plus/mult (convert @0) @1). + 2017-09-29 Bob Duff <duff@adacore.com> * exp_ch6.adb (Expand_Call_Helper): Replace with code more similar to diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 7b30497..e6cd8d6 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -8153,11 +8153,13 @@ annotate_value (tree gnu_size) { tree inner_op_op1 = TREE_OPERAND (inner_op, 1); tree gnu_size_op1 = TREE_OPERAND (gnu_size, 1); - wide_int op1; + widest_int op1; if (TREE_CODE (gnu_size) == MULT_EXPR) - op1 = wi::mul (inner_op_op1, gnu_size_op1); + op1 = (wi::to_widest (inner_op_op1) + * wi::to_widest (gnu_size_op1)); else - op1 = wi::add (inner_op_op1, gnu_size_op1); + op1 = (wi::to_widest (inner_op_op1) + + wi::to_widest (gnu_size_op1)); ops[1] = UI_From_gnu (wide_int_to_tree (sizetype, op1)); ops[0] = annotate_value (TREE_OPERAND (inner_op, 0)); } diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 3c4bd05..58797f0 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2017-10-02 Richard Sandiford <richard.sandiford@linaro.org> + + * c-warn.c (warn_tautological_bitwise_comparison): Use wi::to_widest + when combining the original unconverted comparison operands. + 2017-09-29 Jakub Jelinek <jakub@redhat.com> * c-attribs.c (handle_noipa_attribute): Don't add "stack_protect" diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 0749d16..f86de10 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -355,15 +355,17 @@ warn_tautological_bitwise_comparison (location_t loc, tree_code code, else return; - wide_int res; + /* Note that the two operands are from before the usual integer + conversions, so their types might not be the same. */ + widest_int res; if (TREE_CODE (bitop) == BIT_AND_EXPR) - res = wi::bit_and (bitopcst, cst); + res = wi::to_widest (bitopcst) & wi::to_widest (cst); else - res = wi::bit_or (bitopcst, cst); + res = wi::to_widest (bitopcst) | wi::to_widest (cst); /* For BIT_AND only warn if (CST2 & CST1) != CST1, and for BIT_OR only if (CST2 | CST1) != CST1. */ - if (res == cst) + if (res == wi::to_widest (cst)) return; if (code == EQ_EXPR) diff --git a/gcc/calls.c b/gcc/calls.c index 6bd025e..72cf9e0 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1252,9 +1252,8 @@ alloc_max_size (void) if (unit) { - wide_int w = wi::uhwi (limit, HOST_BITS_PER_WIDE_INT + 64); - w *= unit; - if (wi::ltu_p (w, alloc_object_size_limit)) + widest_int w = wi::mul (limit, unit); + if (w < wi::to_widest (alloc_object_size_limit)) alloc_object_size_limit = wide_int_to_tree (ssizetype, w); } } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4025cb0..cd0433c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2017-10-02 Richard Sandiford <richard.sandiford@linaro.org> + + * constexpr.c (cxx_eval_store_expression): Use wi::to_widest + when comparing the array bounds with an ARRAY_REF index. + 2017-09-30 Paolo Carlini <paolo.carlini@oracle.com> PR c++/68754 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index a89ee49..8a5be20 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3379,7 +3379,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, VERIFY_CONSTANT (nelts); gcc_assert (TREE_CODE (nelts) == INTEGER_CST && TREE_CODE (TREE_OPERAND (probe, 1)) == INTEGER_CST); - if (wi::eq_p (TREE_OPERAND (probe, 1), nelts)) + if (wi::to_widest (TREE_OPERAND (probe, 1)) == wi::to_widest (nelts)) { diag_array_subscript (ctx, ary, TREE_OPERAND (probe, 1)); *non_constant_p = true; diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c index ec95cc6..ab4f9d8 100644 --- a/gcc/gimple-ssa-warn-alloca.c +++ b/gcc/gimple-ssa-warn-alloca.c @@ -491,7 +491,7 @@ pass_walloca::execute (function *fun) is_vla ? G_("argument to variable-length array " "may be too large") : G_("argument to %<alloca%> may be too large")) - && t.limit != integer_zero_node) + && t.limit != 0) { print_decu (t.limit, buff); inform (loc, G_("limit is %u bytes, but argument " @@ -504,7 +504,7 @@ pass_walloca::execute (function *fun) is_vla ? G_("argument to variable-length array " "is too large") : G_("argument to %<alloca%> is too large")) - && t.limit != integer_zero_node) + && t.limit != 0) { print_decu (t.limit, buff); inform (loc, G_("limit is %u bytes, but argument is %s"), diff --git a/gcc/match.pd b/gcc/match.pd index 1136a59..e58a65a 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -358,8 +358,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2) (if (integer_pow2p (@2) && tree_int_cst_sgn (@2) > 0 - && wi::add (@2, @1) == 0 - && tree_nop_conversion_p (type, TREE_TYPE (@0))) + && tree_nop_conversion_p (type, TREE_TYPE (@0)) + && wi::add (@2, @1) == 0) (rshift (convert @0) { build_int_cst (integer_type_node, wi::exact_log2 (@2)); })))) @@ -1883,7 +1883,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && wi::lt_p (@1, prec, TYPE_SIGN (TREE_TYPE (@1))) && wi::ge_p (@2, 0, TYPE_SIGN (TREE_TYPE (@2))) && wi::lt_p (@2, prec, TYPE_SIGN (TREE_TYPE (@2)))) - (with { unsigned int low = wi::add (@1, @2).to_uhwi (); } + (with { unsigned int low = (tree_to_uhwi (@1) + + tree_to_uhwi (@2)); } /* Deal with a OP (c1 + c2) being undefined but (a OP c1) OP c2 being well defined. */ (if (low >= prec) @@ -5176,6 +5176,7 @@ inline wi::storage_ref wi::int_traits <const_tree>::decompose (HOST_WIDE_INT *, unsigned int precision, const_tree x) { + gcc_checking_assert (precision == TYPE_PRECISION (TREE_TYPE (x))); return wi::storage_ref (&TREE_INT_CST_ELT (x, 0), TREE_INT_CST_NUNITS (x), precision); } |