[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 --- 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
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
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
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
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
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
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.