This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/81785] Segmentation fault for signed overflow in index expression when -fwrapv is enabled
- From: "mpolacek at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 17 Aug 2017 09:59:30 +0000
- Subject: [Bug c/81785] Segmentation fault for signed overflow in index expression when -fwrapv is enabled
- Auto-submitted: auto-generated
- References: <bug-81785-4@http.gcc.gnu.org/bugzilla/>
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)