Fix mismatched precisions in tree arithmetic
authorRichard Sandiford <richard.sandiford@linaro.org>
Mon, 2 Oct 2017 09:45:40 +0000 (09:45 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 2 Oct 2017 09:45:40 +0000 (09:45 +0000)
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

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/c-family/ChangeLog
gcc/c-family/c-warn.c
gcc/calls.c
gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/gimple-ssa-warn-alloca.c
gcc/match.pd
gcc/tree.h

index 451580258f730f03be0523ec43b8f70596dd555a..822afa0c88dc1091290ec3b08a6cd8e22b66374e 100644 (file)
@@ -1,3 +1,16 @@
+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>
index 4e931f9a6ff10cb600d7caec2bc47b9876a31a31..848b88faec3cc612eeca4203e10f61237388a228 100644 (file)
@@ -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
index 7b30497587497841f87332de23cfa29dc2e808d3..e6cd8d6ba50eba1becbeb08cd66ed2c5e5a586ae 100644 (file)
@@ -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));
            }
index 3c4bd054e21e87a22d159f3485b563aa7d54eccc..58797f074641ca1bafce1d869f96f7c9a62ba30e 100644 (file)
@@ -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"
index 0749d16a50fb0fa022196640a01afcdab3187edb..f86de10fdd9477d0a72eb503c807d3f6f42932de 100644 (file)
@@ -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)
index 6bd025ed197a3af7db95c190518946582fdbc2c0..72cf9e016c80555a76ef84ef110a8292bdd31876 100644 (file)
@@ -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);
                }
            }
index 4025cb09fb460895b629943f9df25ff9c4f2ac64..cd0433c66cd3c35ee3ddc94f120f3c222140ec6d 100644 (file)
@@ -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
index a89ee4993940fce562a803d38e557f359a20ad84..8a5be2079d8dfdf0e744df65238aec8401696161 100644 (file)
@@ -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;
index ec95cc6ddd87c0858f40032ec30a9be68a3b1e10..ab4f9d82858f4ccbd888926958a8d5af7373925c 100644 (file)
@@ -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"),
index 1136a598abb139673ff54bd57e5bfd7fbe335ac7..e58a65af59b44a6b82ed8705f62966c5e6f251ac 100644 (file)
@@ -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)
index caa4a69977d4c39f3710149246228a0d63c50a73..5e8419e259a58ca6317f5b5b4edfaa079ffaac2d 100644 (file)
@@ -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);
 }