On Thu, Jun 8, 2017 at 12:13 PM, Martin Sebor <mse...@gmail.com> wrote:
> On 06/08/2017 11:00 AM, H.J. Lu wrote:
>>
>> On Wed, Jun 7, 2017 at 6:30 AM, H.J. Lu <hjl.to...@gmail.com> wrote:
>>>
>>> On Tue, Jun 6, 2017 at 5:11 PM, Martin Sebor <mse...@gmail.com> wrote:
>>>>
>>>> On 06/06/2017 04:57 PM, H.J. Lu wrote:
>>>>>
>>>>>
>>>>> On Tue, Jun 6, 2017 at 10:34 AM, Martin Sebor <mse...@gmail.com> wrote:
>>>>>>
>>>>>>
>>>>>> On 06/06/2017 10:59 AM, H.J. Lu wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Jun 6, 2017 at 9:10 AM, Martin Sebor <mse...@gmail.com>
>>>>>>> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On 06/06/2017 10:07 AM, Martin Sebor wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 06/05/2017 11:45 AM, H.J. Lu wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Mon, Jun 5, 2017 at 8:11 AM, Joseph Myers
>>>>>>>>>> <jos...@codesourcery.com>
>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> The new attribute needs documentation.  Should the test be in
>>>>>>>>>>> c-c++-common
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> This feature does support C++.  But C++ compiler issues a slightly
>>>>>>>>>> different warning at a different location.
>>>>>>>>>>
>>>>>>>>>>> or does this feature not support C++?
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Here is the updated patch with documentation and a C++ test.  This
>>>>>>>>>> patch caused a few testsuite failures:
>>>>>>>>>>
>>>>>>>>>> FAIL: gcc.dg/compat/struct-align-1 c_compat_x_tst.o compile
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> /export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.dg/compat//struct-align-1.h:169:1:
>>>>>>>>>>
>>>>>>>>>> warning: alignment 1 of 'struct B2_m_inner_p_outer' is less than
>>>>>>>>>> 16
>>>>>>>>>>
>>>>>>>>>> FAIL: g++.dg/torture/pr80334.C   -O0  (test for excess errors)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/torture/pr80334.C:4:8:
>>>>>>>>>>
>>>>>>>>>> warning: alignment 1 of 'B' is less than 16
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Users often want the ability to control a warning, even when it
>>>>>>>>> certainly indicates a bug.  I would suggest to add an option to
>>>>>>>>> make it possible for this warning as well.
>>>>>>>>>
>>>>>>>>> Btw., a bug related to some of those this warning is meant to
>>>>>>>>> detect is assigning the address of an underaligned object to
>>>>>>>>> a pointer of a natively aligned type.  Clang has an option
>>>>>>>>> to detect this problem: -Waddress-of-packed-member.  It might
>>>>>>>>> make a nice follow-on enhancement to add support for the same
>>>>>>>>> thing.  I mention this because I think it would make sense to
>>>>>>>>> consider this when choosing the name of the GCC option (i.e.,
>>>>>>>>> rather than having two distinct but closely related warnings,
>>>>>>>>> have one that detects both of these alignment type of bugs.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> A bug that has some additional context on this is pr 51628.
>>>>>>>> A possible name for the new option suggested there is -Wpacked.
>>>>>>>>
>>>>>>>> Martin
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Isn't -Waddress-of-packed-member a subset of or the same as
>>>>>>> -Wpacked?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> In Clang it's neither.  -Waddress-of-packed-member only triggers
>>>>>> when the address of a packed member is taken but not for the cases
>>>>>> in bug 53037 (i.e., reducing the alignment of a member).  It's
>>>>>> also enabled by default, while -Wpacked needs to be specified
>>>>>> explicitly (i.e., it's in neither -Wall or -Wextra).
>>>>>>
>>>>>> FWIW, I don't really have a strong opinion about the names of
>>>>>> the options.  My input is that the proliferation of fine-grained
>>>>>> warning options for closely related problems tends to make it
>>>>>> tricky to get their interactions right (both in the compiler
>>>>>> and for users).  Enabling both/all such options can lead to
>>>>>> multiple warnings for what boils down to essentially the same
>>>>>> bug in the same expression, overwhelming the user in repetitive
>>>>>> diagnostics.
>>>>>>
>>>>>
>>>>> There is already -Wpacked.  Should I overload it for this?
>>>>
>>>>
>>>>
>>>> I'd say yes if -Wpacked were at least in -Wall.  But it's
>>>> an opt-in kind of warning that's not even in -Wextra, and
>>>> relaxing an explicitly specified alignment seems more like
>>>> a bug than just something that might be nice to know about.
>>>> I would expect warn_if_not_aligned to trigger a warning even
>>>> without -Wall (i.e., as you have it in your patch, but with
>>>> an option to control it).  That would suggest three levels
>>>> of warnings:
>>>>
>>>> 1) warn by default (warn_if_not_aligned violation)
>>>> 2) warn with -Wall (using a type with attribute aligned to
>>>>    define a member of a packed struct)
>>>> 3) warn if requested (current -Wpacked)
>>>>
>>>> So one way to deal with it would be to change -Wpacked to
>>>> take an argument between 0 and 3, set the default to
>>>> correspond to the (1) above, and have -Wall bump it up to
>>>> (2).
>>>>
>>>> If the equivalent of -Waddress-of-packed-member were to be
>>>> implemented in GCC it would probably be a candidate to add
>>>> to the (2) above.(*)
>>>>
>>>> This might be more involved than you envisioned.  A slightly
>>>> simpler alternative would be to add a different option, say
>>>> something like -Walign=N, and have it handle just (1) and
>>>> (2) above, leaving -Wpacked unchanged.
>>>>
>>>
>>> Since there is no agreement on -W options and changes
>>> may touch many places, I will do
>>>
>>> 1. Add -Wwarn-if-not-aligned and enable it by default.
>>> 2. Add -Wpacked-not-aligned and disable it by default.
>>>
>>> Once there is an agreement, I replace -Wpacked-not-aligned
>>> with the new option.
>
>
> Okay.  I can't approve the patch but thank you for enhancing your
> patch to handle the additional case I brought up!
>
> Martin

Where do we go from here?

>
>> Here is the updated patch.
>>
>> Add warn_if_not_aligned attribute as well as  command line options:
>> -Wif-not-aligned and -Wpacked-not-aligned.
>>
>> __attribute__((warn_if_not_aligned(N))) causes compiler to issue a
>> warning if the field in a struct or union is not aligned to N:
>>
>> typedef unsigned long long __u64
>>   __attribute__((aligned(4),warn_if_not_aligned(8)));
>>
>> struct foo
>> {
>>   int i1;
>>   int i2;
>>   __u64 x;
>> };
>>
>> __u64 is aligned to 4 bytes.  But inside struct foo, __u64 should be
>> aligned at 8 bytes.  It is used to define struct foo in such a way that
>> struct foo has the same layout and x has the same alignment when __u64
>> is aligned at either 4 or 8 bytes.
>>
>> Since struct foo is normally aligned to 4 bytes, a warning will be issued:
>>
>> warning: alignment 4 of ‘struct foo’ is less than 8
>>
>> Align struct foo to 8 bytes:
>>
>> struct foo
>> {
>>   int i1;
>>   int i2;
>>   __u64 x;
>> } __attribute__((aligned(8)));
>>
>> silences the warning.  It also warns the field with misaligned offset:
>>
>> struct foo
>> {
>>   int i1;
>>   int i2;
>>   int i3;
>>   __u64 x;
>> } __attribute__((aligned(8)));
>>
>> warning: ‘x’ offset 12 in ‘struct foo’ isn't aligned to 8
>>
>> This warning is controlled by -Wif-not-aligned and is enabled by default.
>>
>> When -Wpacked-not-aligned is used, the same warning is also issued for
>> the field with explicitly specified alignment in a packed struct or union:
>>
>> struct __attribute__ ((aligned (8))) S8 { char a[8]; };
>> struct __attribute__ ((packed)) S {
>>   struct S8 s8;
>> };
>>
>> warning: alignment 1 of ‘struct S’ is less than 8
>>
>> This warning is disabled by default and enabled by -Wall.
>>
>> gcc/
>>
>> PR c/53037
>> * print-tree.c (print_node): Support DECL_WARN_IF_NOT_ALIGN
>> and TYPE_WARN_IF_NOT_ALIGN.
>> * stor-layout.c (do_type_align): Merge DECL_WARN_IF_NOT_ALIGN.
>> (handle_warn_if_not_align): New.
>> (place_union_field): Call handle_warn_if_not_align.
>> (place_field): Call handle_warn_if_not_align.  Copy
>> TYPE_WARN_IF_NOT_ALIGN.
>> (finish_builtin_struct): Copy TYPE_WARN_IF_NOT_ALIGN.
>> (layout_type): Likewise.
>> * tree-core.h (tree_type_common): Add warn_if_not_align.  Set
>> spare to 18.
>> (tree_decl_common): Add warn_if_not_align.
>> * tree.c (build_range_type_1): Likewise.
>> * tree.h (TYPE_WARN_IF_NOT_ALIGN): New.
>> (SET_TYPE_WARN_IF_NOT_ALIGN): Likewise.
>> (DECL_WARN_IF_NOT_ALIGN): Likewise.
>> (SET_DECL_WARN_IF_NOT_ALIGN): Likewise.
>> * doc/extend.texi: Document warn_if_not_aligned attribute.
>> * doc/invoke.texi: Document -Wif-not-aligned and
>> -Wpacked-not-aligned.
>>
>> gcc/c-family/
>>
>> PR c/53037
>> * c-attribs.c (handle_warn_if_not_aligned_attribute): New.
>> (c_common_attribute_table): Add warn_if_not_aligned.
>> (handle_aligned_attribute): Renamed to ...
>> (common_handle_aligned_attribute): Remove argument, name, and add
>> argument, warn_if_not_aligned.  Handle warn_if_not_aligned.
>> (handle_aligned_attribute): New.
>> * c.opt: Add -Wif-not-aligned and -Wpacked-not-aligned.
>>
>> gcc/c/
>>
>> PR c/53037
>> * c-decl.c (merge_decls): Also merge TYPE_WARN_IF_NOT_ALIGN.
>>
>> gcc/cp/
>>
>> PR c/53037
>> * decl.c (duplicate_decls): Also merge TYPE_WARN_IF_NOT_ALIGN.
>>
>> gcc/testsuite/
>>
>> PR c/53037
>> * c-c++-common/pr53037-4.c: New test.
>> * g++.dg/pr53037-1.C: Likewise.
>> * g++.dg/pr53037-2.C: Likewise.
>> * g++.dg/pr53037-3.C: Likewise.
>> * gcc.dg/pr53037-1.c: Likewise.
>> * gcc.dg/pr53037-2.c: Likewise.
>> * gcc.dg/pr53037-3.c: Likewise.
>>
>>
>



-- 
H.J.

Reply via email to