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

2019-08-28 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

--- Comment #6 from Eric Gallager  ---
(In reply to Marek Polacek from comment #4)
> Looks like removing the optimization regresses c-c++-common/restrict-2.c.

Why would it do that? I don't see any code mentioning restrict being touched...

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

2018-08-29 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

--- Comment #5 from Richard Biener  ---
(In reply to Marek Polacek from comment #4)
> Looks like removing the optimization regresses c-c++-common/restrict-2.c.

Actual code generation or just the number of moved stmts?

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

2017-08-29 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

--- Comment #4 from Marek Polacek  ---
Looks like removing the optimization regresses c-c++-common/restrict-2.c.

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

2017-08-17 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

Marek Polacek  changed:

   What|Removed |Added

 CC||mpolacek at gcc dot gnu.org

--- Comment #3 from Marek Polacek  ---
Re-adding richi's comment.  I'm going to try the following.

--- Comment #3 from Richard Biener  ---
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)

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

2017-08-14 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

Richard Biener  changed:

   What|Removed |Added

   Keywords||wrong-code
 CC||mpolacek at gcc dot gnu.org,
   ||rguenth at gcc dot gnu.org

--- Comment #3 from Richard Biener  ---
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)

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

2017-08-12 Thread mikpelinux at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

Mikael Pettersson  changed:

   What|Removed |Added

 CC||mikpelinux at gmail dot com

--- Comment #2 from Mikael Pettersson  ---
Created attachment 41983
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41983=edit
simple test case

Simpler test case that will __builtin_abort () when the bug hits rather than
segfault.  Problem seems to be that

int * __attribute__((__noinline__, __noclone__))
foo(int x[])
{
int k = INT_MIN;
return [k - INT_MAX];
}

becomes the bogus code

foo:
movabsq $-17179869180, %rax
addq%rdi, %rax
ret

which returns a pointer to a large negative offset off x[], even though -fwrapv
has been passed to gcc.

The equivalent

int * __attribute__((__noinline__, __noclone__))
bar(int x[])
{
return [INT_MIN - INT_MAX];
}

becomes the expected code

bar:
leaq4(%rdi), %rax
ret

although gcc also emits an IMO unwarranted (since -fwrapv is present) warning

pr81785.c: In function 'bar':
pr81785.c:20:23: warning: integer overflow in expression of type 'int' results
in '1' [-Woverflow]
 return [INT_MIN - INT_MAX];

Affects every single gcc since 3.x on x86_64 as far as I can tell.

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

2017-08-11 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81785

Eric Gallager  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2017-08-11
 CC||egallager at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #1 from Eric Gallager  ---
runs fine for me with GCC 8 on i386-apple-darwin9.8.0 (32-bit), but segfaults
on me when I add -m64 to force 64-bit. -Wall -Wextra -Wstrict-overflow=5
-Warray-bounds=2 all print nothing. So confirmed that the code crashes,
although someone else will have to say if GCC is truly the one at fault here.