From 2a06eba5b77e3d85195759db6247271a4802c8e6 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 28 Jan 2019 13:14:37 +0000 Subject: [PATCH] c-warn.c (check_address_or_pointer_of_packed_member): Handle the case when rhs is of array type correctly. 2019-01-28 Bernd Edlinger * c-warn.c (check_address_or_pointer_of_packed_member): Handle the case when rhs is of array type correctly. Fix handling of nested structures. Fix handling of indirect_ref together with nop_expr and/or addr_expr. (check_and_warn_address_or_pointer_of_packed_member): Fix handling of type casts within nested compound expressions. testsuite: 2019-01-28 Bernd Edlinger * c-c++-common/Waddress-of-packed-member-1.c: Extended test case. * c-c++-common/Waddress-of-packed-member-2.c: New test case. From-SVN: r268337 --- gcc/c-family/ChangeLog | 8 +++ gcc/c-family/c-warn.c | 31 +++++++--- gcc/testsuite/ChangeLog | 5 ++ .../Waddress-of-packed-member-1.c | 24 ++++++++ .../Waddress-of-packed-member-2.c | 58 +++++++++++++++++++ 5 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 86efe275366..f955449ec1c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2019-01-28 Bernd Edlinger + + * c-warn.c (check_address_or_pointer_of_packed_member): Handle the case + when rhs is of array type correctly. Fix handling of nested structures. + Fix handling of indirect_ref together with nop_expr and/or addr_expr. + (check_and_warn_address_or_pointer_of_packed_member): Fix handling of + type casts within nested compound expressions. + 2019-01-22 Jakub Jelinek PR middle-end/88968 diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 43b307acafe..e2f3449e694 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -2725,14 +2725,19 @@ static tree check_address_or_pointer_of_packed_member (tree type, tree rhs) { bool rvalue = true; + bool indirect = false; if (INDIRECT_REF_P (rhs)) - rhs = TREE_OPERAND (rhs, 0); + { + rhs = TREE_OPERAND (rhs, 0); + STRIP_NOPS (rhs); + indirect = true; + } if (TREE_CODE (rhs) == ADDR_EXPR) { rhs = TREE_OPERAND (rhs, 0); - rvalue = false; + rvalue = indirect; } if (!POINTER_TYPE_P (type)) @@ -2796,6 +2801,10 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs) if (context) break; } + if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE) + rvalue = false; + if (rvalue) + return NULL_TREE; rhs = TREE_OPERAND (rhs, 0); } @@ -2811,14 +2820,18 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs) static void check_and_warn_address_or_pointer_of_packed_member (tree type, tree rhs) { - bool nop_p; - - while (TREE_CODE (rhs) == COMPOUND_EXPR) - rhs = TREE_OPERAND (rhs, 1); + bool nop_p = false; + tree orig_rhs; - tree orig_rhs = rhs; - STRIP_NOPS (rhs); - nop_p = orig_rhs != rhs; + do + { + while (TREE_CODE (rhs) == COMPOUND_EXPR) + rhs = TREE_OPERAND (rhs, 1); + orig_rhs = rhs; + STRIP_NOPS (rhs); + nop_p |= orig_rhs != rhs; + } + while (orig_rhs != rhs); if (TREE_CODE (rhs) == COND_EXPR) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4796df223a..ab61b302a6d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-01-28 Bernd Edlinger + + * c-c++-common/Waddress-of-packed-member-1.c: Extended test case. + * c-c++-common/Waddress-of-packed-member-2.c: New test case. + 2019-01-28 Bernd Edlinger * gcc.dg/Wattribute-alias.c: Add test for #pragma GCC diagnostic ignored diff --git a/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c b/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c index a1374fb10f4..afad603dfa2 100644 --- a/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c +++ b/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c @@ -6,6 +6,8 @@ struct t { int b; int *c; int d[10]; + int *e[1]; + _Complex float f; } __attribute__((packed)); struct t t0; @@ -17,6 +19,8 @@ struct t *bar(); struct t (*baz())[10]; struct t (*bazz())[10][10]; int *i1; +int **i2; +float f0, *f1; __UINTPTR_TYPE__ u1; __UINTPTR_TYPE__ baa(); @@ -40,6 +44,14 @@ void foo (void) i1 = t10[0].c; /* { dg-bogus "may result in an unaligned pointer value" } */ u1 = (__UINTPTR_TYPE__) &t0; /* { dg-bogus "may result in an unaligned pointer value" } */ u1 = (__UINTPTR_TYPE__) t1; /* { dg-bogus "may result in an unaligned pointer value" } */ + i1 = t10[0].e[0]; /* { dg-bogus "may result in an unaligned pointer value" } */ + i1 = *&t0.c; /* { dg-bogus "may result in an unaligned pointer value" } */ + i1 = *&*&t0.c; /* { dg-bogus "may result in an unaligned pointer value" } */ + f0 = __real__ t0.f; /* { dg-bogus "may result in an unaligned pointer value" } */ + f0 = __imag__ t0.f; /* { dg-bogus "may result in an unaligned pointer value" } */ + f0 = *&__real__ t0.f; /* { dg-bogus "may result in an unaligned pointer value" } */ + f0 = *&__imag__ t0.f; /* { dg-bogus "may result in an unaligned pointer value" } */ + i1 = (&t0.c, (int*) 0); /* { dg-bogus "may result in an unaligned pointer value" } */ t2 = (struct t**) t10; /* { dg-warning "may result in an unaligned pointer value" } */ t2 = (struct t**) t100; /* { dg-warning "may result in an unaligned pointer value" } */ t2 = (struct t**) t1; /* { dg-warning "may result in an unaligned pointer value" } */ @@ -52,4 +64,16 @@ void foo (void) i1 = t0.d; /* { dg-warning "may result in an unaligned pointer value" } */ i1 = t1->d; /* { dg-warning "may result in an unaligned pointer value" } */ i1 = t10[0].d; /* { dg-warning "may result in an unaligned pointer value" } */ + i1 = (int*) &t10[0].e[0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i1 = (int*) t10[0].e; /* { dg-warning "may result in an unaligned pointer value" } */ + i2 = &t10[0].e[0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i2 = t10[0].e; /* { dg-warning "may result in an unaligned pointer value" } */ + i2 = &*&t0.c; /* { dg-warning "may result in an unaligned pointer value" } */ + i2 = &*&*&t0.c; /* { dg-warning "may result in an unaligned pointer value" } */ + f1 = &__real__ t0.f; /* { dg-warning "may result in an unaligned pointer value" } */ + f1 = &__imag__ t0.f; /* { dg-warning "may result in an unaligned pointer value" } */ + i1 = (0, (int*) &t0.c); /* { dg-warning "may result in an unaligned pointer value" } */ + i1 = (int*) (0, &t0.c); /* { dg-warning "may result in an unaligned pointer value" } */ + i1 = (0, (int*)(0, &t0.c));/* { dg-warning "may result in an unaligned pointer value" } */ + i1 = (int*)(0, 1, (void*)(2, 3, (int*)(4, 5, &t0.c)));/* { dg-warning "may result in an unaligned pointer value" } */ } diff --git a/gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c b/gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c new file mode 100644 index 00000000000..65ec5140c9c --- /dev/null +++ b/gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-Waddress-of-packed-member" } */ + +struct r { + int a[10]; + int b[10][10]; + int ****i4; +}; + +struct s { + char c; + struct r p; +} __attribute__((packed)); + +struct t { + char c; + struct r p __attribute__((packed)); + struct r u; +}; + +struct s s0; +struct t t0; +int *i0; + +void foo (void) +{ + i0 = s0.p.a; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = t0.p.a; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = s0.p.b[0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = t0.p.b[0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &s0.p.a[0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &t0.p.a[0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &s0.p.b[0][0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &t0.p.b[0][0]; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = *s0.p.b; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = *t0.p.b; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &**s0.p.b; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &**t0.p.b; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = **&s0.p.b; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = **&t0.p.b; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &*s0.p.a; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = &*t0.p.a; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = *&s0.p.a; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = *&t0.p.a; /* { dg-warning "may result in an unaligned pointer value" } */ + i0 = t0.u.a; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = t0.u.b[0]; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = &t0.u.a[0]; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = &t0.u.b[0][0]; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = *t0.u.b; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = &*t0.u.a; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = &**t0.u.b; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = ***s0.p.i4; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = ***t0.p.i4; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = ****&s0.p.i4; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = ****&t0.p.i4; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = &****s0.p.i4; /* { dg-bogus "may result in an unaligned pointer value" } */ + i0 = &****t0.p.i4; /* { dg-bogus "may result in an unaligned pointer value" } */ +} -- 2.30.2