On 05/14/2018 01:10 PM, H.J. Lu wrote:
On Mon, May 14, 2018 at 10:40 AM, H.J. Lu <hjl.to...@gmail.com> wrote:
$ cat c.i
struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));
long* g8 (struct C *p) { return p; }
$ gcc -O2 -S c.i -Wno-incompatible-pointer-types
c.i: In function ‘g8’:
c.i:4:33: warning: taking value of packed 'struct C *' may result in an
unaligned pointer value [-Waddress-of-packed-member]
^^^^^
That should read "taking address" (not value) but...
The value of 'struct C *' is an address. There is no address taken here.
...to help explain the problem I would suggest to mention the expected
and actual alignment in the warning message. E.g.,
storing the address of a packed 'struct C' in 'struct C *' increases the
alignment of the pointer from 1 to 4.
I will take a look.
(IIUC, the source type and destination type need not be the same so
including both should be helpful in those cases.)
Adding a note pointing to the declaration of either the struct or
the member would help users find it if it's a header far removed
from the point of use.
I will see what I can do.
How about this
[hjl@gnu-skx-1 pr51628]$ cat n9.i
struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));
long* g8 (struct C *p) { return p; }
[hjl@gnu-skx-1 pr51628]$
/export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n9.i
n9.i: In function ‘g8’:
n9.i:4:33: warning: returning ‘struct C *’ from a function with
incompatible return type ‘long int *’ [-Wincompatible-pointer-types]
long* g8 (struct C *p) { return p; }
^
n9.i:4:33: warning: taking value of packed ‘struct C *’ increases the
alignment of the pointer from 1 to 8 [-Waddress-of-packed-member]
n9.i:2:8: note: defined here
struct C { struct B b; } __attribute__ ((packed));
Mentioning the alignments looks good.
I still find the "taking value" phrasing odd. I think we would
describe what's going on as "converting a pointer to a packed C
to a pointer to C (with an alignment of 8)" so I'd suggest to
use the term converting instead.
I also think mentioning both the source and the destination types
is useful irrespective of -Wincompatible-pointer-types because
the latter is often suppressed using a cast, as in:
struct __attribute__ ((packed)) A { int i; };
struct B {
struct A a;
} b;
long *p = (long*)&b.a.i; // -Waddress-of-packed-member
int *q = (int*)&b.a; // missing warning
If the types above were obfuscated by macros, typedefs, or in
C++ template parameters, it could be difficult to figure out
what the type of the member is because neither it nor the name
of the member appears in the message.
Martin