Hi, unfortunately there are some more issues with -Waddress-of-packed-member, that show that my previous patch was not yet complete.
That is a bogus warning, in C and C++ (see addition in test case 1), and a couple of missing warnings in C++ (test case 2). The latter warning regressions were accidentally introduced by my previous patch, sorry. As a side note, the generic tree for an expression like struct.array is folded differently by C and C++ FE. While C folds that to &struct.array, C++ folds it to struct.array, without the ADDR_EXPR. That might help to explain why this needs to be done in this slightly confusing way. Fixed the warning regression, and added some more test cases. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd.
2019-01-22 Bernd Edlinger <bernd.edlin...@hotmail.de> PR c/88928 * 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. testsuite: 2019-01-22 Bernd Edlinger <bernd.edlin...@hotmail.de> PR c/88928 * c-c++-common/Waddress-of-packed-member-1.c: Extended test case. * c-c++-common/Waddress-of-packed-member-2.c: New test case. Index: gcc/c-family/c-warn.c =================================================================== --- gcc/c-family/c-warn.c (revision 268119) +++ gcc/c-family/c-warn.c (working copy) @@ -2796,6 +2796,10 @@ check_address_or_pointer_of_packed_membe if (context) break; } + if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE) + rvalue = false; + if (rvalue) + return NULL_TREE; rhs = TREE_OPERAND (rhs, 0); } Index: gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c =================================================================== --- gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c (revision 268119) +++ gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c (working copy) @@ -6,6 +6,7 @@ struct t { int b; int *c; int d[10]; + int *e[1]; } __attribute__((packed)); struct t t0; @@ -40,6 +41,7 @@ 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" } */ 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 +54,6 @@ 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" } */ } Index: gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c =================================================================== --- gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c (revision 0) +++ gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c (working copy) @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-Waddress-of-packed-member" } */ + +struct r { + int a[10]; + int b[10][10]; +}; + +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 = 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" } */ +}