This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/81785] Segmentation fault for signed overflow in index expression when -fwrapv is enabled


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mpolacek at gcc dot gnu.org

--- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Re-adding richi's comment.  I'm going to try the following.

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
We emit

    int k = -2147483648;
  return x + ((sizetype) ((long unsigned int) k * 4) + 18446744065119617028);

and it seems we end up zero-extending k.  I believe that's because of the
(premature) optimization in pointer_int_sum:

  /* If what we are about to multiply by the size of the elements
     contains a constant term, apply distributive law
     and multiply that constant term separately.
     This helps produce common subexpressions.  */
  if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
      && !TREE_CONSTANT (intop)
      && TREE_CONSTANT (TREE_OPERAND (intop, 1))
      && TREE_CONSTANT (size_exp)
      /* If the constant comes from pointer subtraction,
         skip this optimization--it would cause an error.  */
      && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE
      /* If the constant is unsigned, and smaller than the pointer size,
         then we must skip this optimization.  This is because it could cause
         an overflow error if the constant is negative but INTOP is not.  */
      && (!TYPE_UNSIGNED (TREE_TYPE (intop))
          || (TYPE_PRECISION (TREE_TYPE (intop))
              == TYPE_PRECISION (TREE_TYPE (ptrop)))))
    {
      enum tree_code subcode = resultcode;
      tree int_type = TREE_TYPE (intop);
      if (TREE_CODE (intop) == MINUS_EXPR)
        subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
      /* Convert both subexpression types to the type of intop,
         because weird cases involving pointer arithmetic
         can result in a sum or difference with different type args.  */
      ptrop = build_binary_op (EXPR_LOCATION (TREE_OPERAND (intop, 1)),
                               subcode, ptrop,
                               convert (int_type, TREE_OPERAND (intop, 1)),
                               true);
      intop = convert (int_type, TREE_OPERAND (intop, 0));
    }


compilable testcase:

int * __attribute__((__noinline__, __noclone__))
foo(int x[])
{
  int k = (-__INT_MAX__ - 1);
  return x + (k - __INT_MAX__);
}

I suggest trying to remove the above...  (doing so fixes the testcase)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]