Re: [PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-06-18 Thread Joseph Myers
On Mon, 18 Jun 2018, Jason Merrill wrote:

> On Mon, Jun 18, 2018 at 11:59 AM, Joseph Myers  
> wrote:
> > On Mon, 18 Jun 2018, Jason Merrill wrote:
> >
> >> > +  if (TREE_CODE (rhs) == COND_EXPR)
> >> > +{
> >> > +  /* Check the THEN path first.  */
> >> > +  tree op1 = TREE_OPERAND (rhs, 1);
> >> > +  context = check_address_of_packed_member (type, op1);
> >>
> >> This should handle the GNU extension of re-using operand 0 if operand
> >> 1 is omitted.
> >
> > Doesn't that just use a SAVE_EXPR?
> 
> Hmm, I suppose it does, but many places in the compiler seem to expect
> that it produces a COND_EXPR with TREE_OPERAND 1 as NULL_TREE.

Maybe that's used somewhere inside the C++ front end.  For C a SAVE_EXPR 
is produced directly.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-06-18 Thread Jason Merrill
On Mon, Jun 18, 2018 at 11:59 AM, Joseph Myers  wrote:
> On Mon, 18 Jun 2018, Jason Merrill wrote:
>
>> > +  if (TREE_CODE (rhs) == COND_EXPR)
>> > +{
>> > +  /* Check the THEN path first.  */
>> > +  tree op1 = TREE_OPERAND (rhs, 1);
>> > +  context = check_address_of_packed_member (type, op1);
>>
>> This should handle the GNU extension of re-using operand 0 if operand
>> 1 is omitted.
>
> Doesn't that just use a SAVE_EXPR?

Hmm, I suppose it does, but many places in the compiler seem to expect
that it produces a COND_EXPR with TREE_OPERAND 1 as NULL_TREE.
Perhaps that code is obsolete.  Never mind it here, then.

Jason


Re: [PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-06-18 Thread Joseph Myers
On Mon, 18 Jun 2018, Jason Merrill wrote:

> > +  if (TREE_CODE (rhs) == COND_EXPR)
> > +{
> > +  /* Check the THEN path first.  */
> > +  tree op1 = TREE_OPERAND (rhs, 1);
> > +  context = check_address_of_packed_member (type, op1);
> 
> This should handle the GNU extension of re-using operand 0 if operand
> 1 is omitted.

Doesn't that just use a SAVE_EXPR?

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-06-18 Thread Jason Merrill
On Fri, May 18, 2018 at 7:36 AM, H.J. Lu  wrote:
> On Thu, May 17, 2018 at 10:32:56AM -0700, H.J. Lu wrote:
>> On Mon, May 14, 2018 at 8:00 PM, Martin Sebor  wrote:
>> > On 05/14/2018 01:10 PM, H.J. Lu wrote:
>> >>
>> >> On Mon, May 14, 2018 at 10:40 AM, H.J. Lu  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.
>>
>> How about this?
>>
>> [hjl@gnu-skx-1 pr51628]$ cat n12.i
>> struct B { int i; };
>> struct C { struct B b; } __attribute__ ((packed));
>>
>> struct B* g8 (struct C *p) { return p; }
>> [hjl@gnu-skx-1 pr51628]$ make n12.s
>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n12.i
>> n12.i: In function ‘g8’:
>> n12.i:4:37: warning: returning ‘struct C *’ from a function with
>> incompatible return type ‘struct B *’ [-Wincompatible-pointer-types]
>>  struct B* g8 (struct C *p) { return p; }
>>  ^
>> n12.i:4:37: warning: converting a pointer to packed ‘struct C *’
>> increases the alignment of the pointer to ‘struct B *’ from 1 to 4
>> [-Waddress-of-packed-member]
>> n12.i:2:8: note: defined here
>>  struct C { struct B b; } __attribute__ ((packed));
>> ^
>> n12.i:1:8: note: defined here
>>  struct B { int i; };
>> ^
>> [hjl@gnu-skx-1 pr51628]$
>>
>> > 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*)   // -Waddress-of-packed-member
>> >   int *q = (int*)   // 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.
>>
>> How about this
>>
>> [hjl@gnu-skx-1 pr51628]$ cat n13.i
>> struct __attribute__ ((packed)) A { int i; };
>> struct B {
>>   struct A a;
>> } b;
>>
>> long *p = (long*)
>> int *q = (int*)
>> [hjl@gnu-skx-1 pr51628]$ make n13.s
>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n13.i
>> n13.i:6:18: warning: taking address of packed member of ‘struct A’ may
>> result in an unaligned pointer value [-Waddress-of-packed-member]
>>  long *p = (long*)
>>   ^~
>> 

PING^2: [PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-06-12 Thread H.J. Lu
On Tue, May 29, 2018 at 5:15 AM, H.J. Lu  wrote:
> On Fri, May 18, 2018 at 4:36 AM, H.J. Lu  wrote:
>> On Thu, May 17, 2018 at 10:32:56AM -0700, H.J. Lu wrote:
>>> On Mon, May 14, 2018 at 8:00 PM, Martin Sebor  wrote:
>>> > On 05/14/2018 01:10 PM, H.J. Lu wrote:
>>> >>
>>> >> On Mon, May 14, 2018 at 10:40 AM, H.J. Lu  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.
>>>
>>> How about this?
>>>
>>> [hjl@gnu-skx-1 pr51628]$ cat n12.i
>>> struct B { int i; };
>>> struct C { struct B b; } __attribute__ ((packed));
>>>
>>> struct B* g8 (struct C *p) { return p; }
>>> [hjl@gnu-skx-1 pr51628]$ make n12.s
>>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n12.i
>>> n12.i: In function ‘g8’:
>>> n12.i:4:37: warning: returning ‘struct C *’ from a function with
>>> incompatible return type ‘struct B *’ [-Wincompatible-pointer-types]
>>>  struct B* g8 (struct C *p) { return p; }
>>>  ^
>>> n12.i:4:37: warning: converting a pointer to packed ‘struct C *’
>>> increases the alignment of the pointer to ‘struct B *’ from 1 to 4
>>> [-Waddress-of-packed-member]
>>> n12.i:2:8: note: defined here
>>>  struct C { struct B b; } __attribute__ ((packed));
>>> ^
>>> n12.i:1:8: note: defined here
>>>  struct B { int i; };
>>> ^
>>> [hjl@gnu-skx-1 pr51628]$
>>>
>>> > 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*)   // -Waddress-of-packed-member
>>> >   int *q = (int*)   // 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.
>>>
>>> How about this
>>>
>>> [hjl@gnu-skx-1 pr51628]$ cat n13.i
>>> struct __attribute__ ((packed)) A { int i; };
>>> struct B {
>>>   struct A a;
>>> } b;
>>>
>>> long *p = (long*)
>>> int *q = (int*)
>>> [hjl@gnu-skx-1 pr51628]$ make n13.s
>>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n13.i
>>> n13.i:6:18: 

PING^1: [PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-05-29 Thread H.J. Lu
On Fri, May 18, 2018 at 4:36 AM, H.J. Lu  wrote:
> On Thu, May 17, 2018 at 10:32:56AM -0700, H.J. Lu wrote:
>> On Mon, May 14, 2018 at 8:00 PM, Martin Sebor  wrote:
>> > On 05/14/2018 01:10 PM, H.J. Lu wrote:
>> >>
>> >> On Mon, May 14, 2018 at 10:40 AM, H.J. Lu  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.
>>
>> How about this?
>>
>> [hjl@gnu-skx-1 pr51628]$ cat n12.i
>> struct B { int i; };
>> struct C { struct B b; } __attribute__ ((packed));
>>
>> struct B* g8 (struct C *p) { return p; }
>> [hjl@gnu-skx-1 pr51628]$ make n12.s
>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n12.i
>> n12.i: In function ‘g8’:
>> n12.i:4:37: warning: returning ‘struct C *’ from a function with
>> incompatible return type ‘struct B *’ [-Wincompatible-pointer-types]
>>  struct B* g8 (struct C *p) { return p; }
>>  ^
>> n12.i:4:37: warning: converting a pointer to packed ‘struct C *’
>> increases the alignment of the pointer to ‘struct B *’ from 1 to 4
>> [-Waddress-of-packed-member]
>> n12.i:2:8: note: defined here
>>  struct C { struct B b; } __attribute__ ((packed));
>> ^
>> n12.i:1:8: note: defined here
>>  struct B { int i; };
>> ^
>> [hjl@gnu-skx-1 pr51628]$
>>
>> > 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*)   // -Waddress-of-packed-member
>> >   int *q = (int*)   // 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.
>>
>> How about this
>>
>> [hjl@gnu-skx-1 pr51628]$ cat n13.i
>> struct __attribute__ ((packed)) A { int i; };
>> struct B {
>>   struct A a;
>> } b;
>>
>> long *p = (long*)
>> int *q = (int*)
>> [hjl@gnu-skx-1 pr51628]$ make n13.s
>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n13.i
>> n13.i:6:18: warning: taking address of packed member of ‘struct A’ may
>> result in an unaligned pointer value [-Waddress-of-packed-member]
>>  long *p = (long*)
>>   ^~
>> 

[PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-05-18 Thread H.J. Lu
On Thu, May 17, 2018 at 10:32:56AM -0700, H.J. Lu wrote:
> On Mon, May 14, 2018 at 8:00 PM, Martin Sebor  wrote:
> > On 05/14/2018 01:10 PM, H.J. Lu wrote:
> >>
> >> On Mon, May 14, 2018 at 10:40 AM, H.J. Lu  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.
> 
> How about this?
> 
> [hjl@gnu-skx-1 pr51628]$ cat n12.i
> struct B { int i; };
> struct C { struct B b; } __attribute__ ((packed));
> 
> struct B* g8 (struct C *p) { return p; }
> [hjl@gnu-skx-1 pr51628]$ make n12.s
> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n12.i
> n12.i: In function ‘g8’:
> n12.i:4:37: warning: returning ‘struct C *’ from a function with
> incompatible return type ‘struct B *’ [-Wincompatible-pointer-types]
>  struct B* g8 (struct C *p) { return p; }
>  ^
> n12.i:4:37: warning: converting a pointer to packed ‘struct C *’
> increases the alignment of the pointer to ‘struct B *’ from 1 to 4
> [-Waddress-of-packed-member]
> n12.i:2:8: note: defined here
>  struct C { struct B b; } __attribute__ ((packed));
> ^
> n12.i:1:8: note: defined here
>  struct B { int i; };
> ^
> [hjl@gnu-skx-1 pr51628]$
> 
> > 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*)   // -Waddress-of-packed-member
> >   int *q = (int*)   // 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.
> 
> How about this
> 
> [hjl@gnu-skx-1 pr51628]$ cat n13.i
> struct __attribute__ ((packed)) A { int i; };
> struct B {
>   struct A a;
> } b;
> 
> long *p = (long*)
> int *q = (int*)
> [hjl@gnu-skx-1 pr51628]$ make n13.s
> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n13.i
> n13.i:6:18: warning: taking address of packed member of ‘struct A’ may
> result in an unaligned pointer value [-Waddress-of-packed-member]
>  long *p = (long*)
>   ^~
> n13.i:7:16: warning: taking address of packed member of ‘struct B’ may
> result in an unaligned pointer value [-Waddress-of-packed-member]
>  int