On Mon, May 14, 2018 at 9:18 AM, Martin Sebor <mse...@gmail.com> wrote:
> On 05/14/2018 07:44 AM, H.J. Lu wrote:
>>
>> On Wed, Apr 25, 2018 at 7:54 PM, H.J. Lu <hongjiu...@intel.com> wrote:
>>>
>>> When address of packed member of struct or union is taken, it may result
>>> in an unaligned pointer value.  This patch adds
>>> -Waddress-of-packed-member
>>> to check alignment at pointer assignment and warn unaligned address as
>>> well as unaligned pointer:
>
>
> This isn't a complete review, just some high level observations
> and suggestions for things I noticed.
>
>>> $ cat x.i
>>> struct pair_t
>>> {
>>>   char c;
>>>   int i;
>>> } __attribute__ ((packed));
>>>
>>> extern struct pair_t p;
>>> int *addr = &p.i;
>>> $ gcc -O2 -S x.i
>>> x.i:8:13:  warning: taking address of packed member of 'struct pair_t'
>>> may result in an unaligned pointer value [-Waddress-of-packed-member]
>>>  int *addr = &p.i;
>>>              ^
>>> $ 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.

> Here's a question: Should the following trigger the warning (it
> doesn't, either with your patch or with Clang, even though the
> pointer is misaligned).
>
>   struct __attribute__ ((packed)) A { int i; } a;
>   struct B: A { int j; } b;
>
>   int B::*pbi = &A::i;

Can you show the misaligned pointer in the generated code?

>>>  long* g8 (struct C *p) { return p; }
>>>                                  ^
>>> $
>>>
>>> This warning is enabled by default.
>
>
> Can you please explain the reasoning behind this decision?
>
> Is it because the warning is meant to have no false positives
> (and the GCC diagnostic guidelines suggest that such warnings
> be on by default), or because Clang enables it by default?

I don't have strong opinion here.

> I ask because the phrasing of the warning "may result" suggests

"may result" is used since 4-byte alignment is also 1-byte alignment.

> it's not free of false positives.  I'm probably missing something,
> and so...
>
> ...I would suggest to expand the documentation a bit and add
> an example showing when the warning triggers, when it doesn't.
> The added text says that taking the address of a packed member
> "usually results in an unaligned pointer value."  When does it
> not result in one?  Would a warning in such cases be a false
> positive?

Since any alignment is 1-byte alignment, a 1-byte aligned address
may be 8-byte aligned.

>
>>>  Since read_encoded_value_with_base
>>> in unwind-pe.h has
>>>
>>>   union unaligned
>>>     {
>>>       void *ptr;
>>>       unsigned u2 __attribute__ ((mode (HI)));
>>>       unsigned u4 __attribute__ ((mode (SI)));
>>>       unsigned u8 __attribute__ ((mode (DI)));
>>>       signed s2 __attribute__ ((mode (HI)));
>>>       signed s4 __attribute__ ((mode (SI)));
>>>       signed s8 __attribute__ ((mode (DI)));
>>>     } __attribute__((__packed__));
>>>   _Unwind_Internal_Ptr result;
>>>
>>> and GCC warns:
>>>
>>> gcc/libgcc/unwind-pe.h:210:37: warning: taking address of packed member
>>> of 'union unaligned' may result in an unaligned pointer value
>>> [-Waddress-of-packed-member]
>>>     result = (_Unwind_Internal_Ptr) u->ptr;
>>>                                     ^
>>> we need to add GCC pragma to ignore -Waddress-of-packed-member.
>>>
>>> OK for trunk?
>>>
>>> H.J.
>>> ----
>>> gcc/c/
>>>
>>>         PR c/51628
>>>         * doc/invoke.texi: Document -Wno-address-of-packed-member.
>>>
>>> gcc/c-family/
>>>
>>>         PR c/51628
>>>         * c-common.h (warn_for_address_of_packed_member): New.
>>>         * c-warn.c (check_address_of_packed_member): New function.
>>>         (warn_for_address_of_packed_member): Likewise.
>>>         * c.opt: Add -Wno-address-of-packed-member.
>>>
>>> gcc/c/
>>>
>>>         PR c/51628
>>>         * c-typeck.c (warn_for_pointer_of_packed_member): New function.
>>>         (convert_for_assignment): Call warn_for_address_of_packed_member
>>>         and warn_for_pointer_of_packed_member.
>
>
> The comment in the hunk below refers to symbols that don't correspond
> to any of the arguments (ERRTYPE, PARNUM, and NAME).
>
> +/* Warn if the right hand poiner value RHS isn't aligned to a
> +   pointer type TYPE.  ERRTYPE says whether it is argument passing,
> +   assignment, initialization or return.  PARMNUM is the number of
> +   the argument, for printing in error messages.  NAME is the name
> +   of the function.  */
> +
> +static void
> +warn_for_pointer_of_packed_member (location_t location, tree type,
> +                                  tree rhs)
> +{
>
> Similarly, in the hunk below, LHS doesn't refer to any variable
> either used or declared in the context.


I will fix them.

> @@ -6986,6 +7037,13 @@ convert_for_assignment (location_t location,
> location_t expr_loc, tree type,
>             }
>         }
>
> +      /* If LHS is't an address, check pointer or array of packed
> +        struct or union.  */
> +      if (TREE_CODE (orig_rhs) != ADDR_EXPR)
> +       warn_for_pointer_of_packed_member (location, type, orig_rhs);
> +      else
> +       warn_for_address_of_packed_member (type, orig_rhs);
> +
>
> Martin
>

Thanks.

-- 
H.J.

Reply via email to