From: Richard Sandiford Date: Thu, 18 Apr 2019 12:29:56 +0000 (+0000) Subject: Fix two ubsan failures (PR85164) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cd7f7c54a43c435152b2ac76b6e74ae6a3430472;p=gcc.git Fix two ubsan failures (PR85164) Two fixes for UB when handling very large offsets. The calculation in force_int_to_mode would have been correct if signed integers used modulo arithmetic, so just switch to unsigned types. The calculation in rtx_addr_can_trap_p_1 didn't handle overflow properly, so switch to known_subrange_p instead (which is supposed to handle all cases). 2019-04-18 Richard Sandiford gcc/ PR middle-end/85164 * combine.c (force_int_to_mode): Cast the argument rather than the result of known_alignment. * rtlanal.c (rtx_addr_can_trap_p_1): Use known_subrange_p. gcc/testsuite/ PR middle-end/85164 * gcc.dg/pr85164-1.c, gcc.dg/pr85164-2.c: New tests. From-SVN: r270442 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e589a9e7517..8dba1ed7bf3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-04-18 Richard Sandiford + + PR middle-end/85164 + * combine.c (force_int_to_mode): Cast the argument rather than + the result of known_alignment. + * rtlanal.c (rtx_addr_can_trap_p_1): Use known_subrange_p. + 2019-04-18 Richard Biener PR debug/90131 diff --git a/gcc/combine.c b/gcc/combine.c index 5616e6b1bac..4de759a8e6b 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -8946,7 +8946,7 @@ force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode, /* If X is (minus C Y) where C's least set bit is larger than any bit in the mask, then we may replace with (neg Y). */ if (poly_int_rtx_p (XEXP (x, 0), &const_op0) - && (unsigned HOST_WIDE_INT) known_alignment (const_op0) > mask) + && known_alignment (poly_uint64 (const_op0)) > mask) { x = simplify_gen_unary (NEG, xmode, XEXP (x, 1), xmode); return force_to_mode (x, mode, mask, next_select); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 3873b4098b0..268a38799d6 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -521,7 +521,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, poly_int64 offset, poly_int64 size, return (!known_size_p (decl_size) || known_eq (decl_size, 0) ? maybe_ne (offset, 0) - : maybe_gt (offset + size, decl_size)); + : !known_subrange_p (offset, size, 0, decl_size)); } return 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ee03b5e9b55..451f190b195 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-18 Richard Sandiford + + PR middle-end/85164 + * gcc.dg/pr85164-1.c, gcc.dg/pr85164-2.c: New tests. + 2019-04-18 Richard Biener PR debug/90131 diff --git a/gcc/testsuite/gcc.dg/pr85164-1.c b/gcc/testsuite/gcc.dg/pr85164-1.c new file mode 100644 index 00000000000..4c5995e8875 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr85164-1.c @@ -0,0 +1,7 @@ +/* { dg-options "-O2 -w" } */ +a[]; +b; +c() { + unsigned long d; + b = a[d - 1 >> 3]; +} diff --git a/gcc/testsuite/gcc.dg/pr85164-2.c b/gcc/testsuite/gcc.dg/pr85164-2.c new file mode 100644 index 00000000000..9e9a7db2bf2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr85164-2.c @@ -0,0 +1,4 @@ +/* { dg-options "-O2 -w" } */ +int a; +long b; +void c() { b = -9223372036854775807L - 1 - a; }