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

Reply via email to