aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-10-02 09:45:40 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-10-02 09:45:40 +0000
commita1488398d4abf50ff8b2ec25d6a75185aefc52c8 (patch)
treee5cca47aca114b176833f91da6a74b6829051ce5
parent1a6da556c414bbbec6df82fdb342e8b84e205507 (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/decl.c8
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-warn.c10
-rw-r--r--gcc/calls.c5
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c2
-rw-r--r--gcc/gimple-ssa-warn-alloca.c4
-rw-r--r--gcc/match.pd7
-rw-r--r--gcc/tree.h1
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)
diff --git a/gcc/tree.h b/gcc/tree.h
index caa4a69..5e8419e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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);
}