On Tue, May 29, 2018 at 5:15 AM, H.J. Lu <hjl.to...@gmail.com> wrote:
> On Fri, May 18, 2018 at 4:36 AM, H.J. Lu <hjl.to...@gmail.com> 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 <mse...@gmail.com> wrote:
>>> > 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.
>>>
>>> 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*)&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.
>>>
>>> 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*)&b.a.i;
>>> int *q = (int*)&b.a;
>>> [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*)&b.a.i;
>>>                   ^~~~~~
>>> 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 *q = (int*)&b.a;
>>>                 ^~~~
>>> [hjl@gnu-skx-1 pr51628]$
>>>
>>>
>>
>> Here is the updated patch.  OK for trunk?
>>
>>
>
> PING:
>
> https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00890.html
>

PING.


-- 
H.J.

Reply via email to