From: Jakub Jelinek Date: Tue, 16 Jan 2018 15:08:32 +0000 (+0100) Subject: re PR c/83844 (ICE with warn_if_not_aligned attribute) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=38943500babbfda935c1108a16ecbb03cb1a33e8;p=gcc.git re PR c/83844 (ICE with warn_if_not_aligned attribute) PR c/83844 * stor-layout.c (handle_warn_if_not_align): Use byte_position and multiple_of_p instead of unchecked tree_to_uhwi and UHWI check. If off is not INTEGER_CST, issue a may not be aligned warning rather than isn't aligned. Use isn%'t rather than isn't. * fold-const.c (multiple_of_p) : Don't fall through into MULT_EXPR. : Improve the case when bottom and one of the MULT_EXPR operands are INTEGER_CSTs and bottom is multiple of that operand, in that case check if the other operand is multiple of bottom divided by the INTEGER_CST operand. * gcc.dg/pr83844.c: New test. From-SVN: r256745 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index abe3295e61e..9b7bf83cb77 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2018-01-16 Jakub Jelinek + + PR c/83844 + * stor-layout.c (handle_warn_if_not_align): Use byte_position and + multiple_of_p instead of unchecked tree_to_uhwi and UHWI check. + If off is not INTEGER_CST, issue a may not be aligned warning + rather than isn't aligned. Use isn%'t rather than isn't. + * fold-const.c (multiple_of_p) : Don't fall through + into MULT_EXPR. + : Improve the case when bottom and one of the + MULT_EXPR operands are INTEGER_CSTs and bottom is multiple of that + operand, in that case check if the other operand is multiple of + bottom divided by the INTEGER_CST operand. + 2018-01-16 Richard Sandiford PR target/83858 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5cf20521daf..1ea37666131 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -12595,9 +12595,34 @@ multiple_of_p (tree type, const_tree top, const_tree bottom) a multiple of BOTTOM then TOP is a multiple of BOTTOM. */ if (!integer_pow2p (bottom)) return 0; - /* FALLTHRU */ + return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom) + || multiple_of_p (type, TREE_OPERAND (top, 0), bottom)); case MULT_EXPR: + if (TREE_CODE (bottom) == INTEGER_CST) + { + op1 = TREE_OPERAND (top, 0); + op2 = TREE_OPERAND (top, 1); + if (TREE_CODE (op1) == INTEGER_CST) + std::swap (op1, op2); + if (TREE_CODE (op2) == INTEGER_CST) + { + if (multiple_of_p (type, op2, bottom)) + return 1; + /* Handle multiple_of_p ((x * 2 + 2) * 4, 8). */ + if (multiple_of_p (type, bottom, op2)) + { + widest_int w = wi::sdiv_trunc (wi::to_widest (bottom), + wi::to_widest (op2)); + if (wi::fits_to_tree_p (w, TREE_TYPE (bottom))) + { + op2 = wide_int_to_tree (TREE_TYPE (bottom), w); + return multiple_of_p (type, op1, op2); + } + } + return multiple_of_p (type, op1, bottom); + } + } return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom) || multiple_of_p (type, TREE_OPERAND (top, 0), bottom)); diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 0f65e166411..8c415ebb6ac 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1150,12 +1150,16 @@ handle_warn_if_not_align (tree field, unsigned int record_align) warning (opt_w, "alignment %u of %qT is less than %u", record_align, context, warn_if_not_align); - unsigned HOST_WIDE_INT off - = (tree_to_uhwi (DECL_FIELD_OFFSET (field)) - + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field)) / BITS_PER_UNIT); - if ((off % warn_if_not_align) != 0) - warning (opt_w, "%q+D offset %wu in %qT isn't aligned to %u", - field, off, context, warn_if_not_align); + tree off = byte_position (field); + if (!multiple_of_p (TREE_TYPE (off), off, size_int (warn_if_not_align))) + { + if (TREE_CODE (off) == INTEGER_CST) + warning (opt_w, "%q+D offset %E in %qT isn%'t aligned to %u", + field, off, context, warn_if_not_align); + else + warning (opt_w, "%q+D offset %E in %qT may not be aligned to %u", + field, off, context, warn_if_not_align); + } } /* Called from place_field to handle unions. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9bc4d7be97c..ec9f4695cc3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-01-16 Jakub Jelinek + + PR c/83844 + * gcc.dg/pr83844.c: New test. + 2018-01-16 Richard Sandiford * gcc.dg/torture/pr83847.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr83844.c b/gcc/testsuite/gcc.dg/pr83844.c new file mode 100644 index 00000000000..c6db68af2c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83844.c @@ -0,0 +1,36 @@ +/* PR c/83844 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wall" } */ + +typedef unsigned long long __u64 __attribute__((aligned(4),warn_if_not_aligned(8))); +void bar (void *, void *, void *); + +void +foo (int n) +{ + struct A + { + int i1; + int i2; + int i3[n]; + __u64 x; /* { dg-warning "in 'struct A' may not be aligned to 8" } */ + } __attribute__((aligned (8))); + struct B + { + int i1; + int i2; + long long i3[n]; + __u64 x; + } __attribute__((aligned (8))); + struct C + { + int i1; + int i2; + int i3[2 * n]; + __u64 x; + } __attribute__((aligned (8))); + struct A a; + struct B b; + struct C c; + bar (&a, &b, &c); +}