Bug 52981 - Separate -Wpadded into two options
Summary: Separate -Wpadded into two options
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.7.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
: 53514 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-04-13 18:31 UTC by Aaron S. Kurland
Modified: 2022-08-22 09:43 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-12-22 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Aaron S. Kurland 2012-04-13 18:31:06 UTC
The option -Wpacked reports two different warnings:

1. warning: padding struct to align ‘<member name>’
2. warning: padding struct size to alignment boundary

The first warning indicates that the structure can be reordered in such a way as to reduce padding. The second warning simply indicates that the structure is not a multiple of the largest primitive data type and required padding at the end.

I find the first warning much more interesting than the second one. Specifically I would like to control them individually using -Werror.

If we can add something like -Wpacked-align and -Wpacked-size as additional options (while still preserving the behavior of -Wpacked) I think this would be a valuable addition to GCC.
Comment 1 Aaron S. Kurland 2012-10-24 15:22:28 UTC
I just realized that my original message was referring to the wrong option. I meant: -Wpadded

I am therefore requesting two new options:

-Wpadded-element and -Wpadded-structure

Sorry for the confusion.
Comment 2 Roger Lynn 2014-10-09 10:49:25 UTC
Note that bug 53514 is essentially the same bug for C++.

If I enable -Wpadded I am flooded with "padding struct size to alignment boundary" warnings, which makes it difficult to find the rarer and much more useful "padding struct to align ‘<member name>’" warnings.
Comment 3 Manuel López-Ibáñez 2014-10-09 11:23:20 UTC
*** Bug 53514 has been marked as a duplicate of this bug. ***
Comment 4 Manuel López-Ibáñez 2014-10-09 11:27:39 UTC
This is quite easy to implement. Just add the two new options [*] to common.opt, add EnabledBy(Wpadding) to them, then update the uses of OPT_Wpadded and warn_padded throughout the source code and testsuite, then update doc/invoke.texi. Bootstrap + regression test, submit patch, ping patch until approved by a maintainer. Commit and add a note to gcc-5/changes.html. Easy to do, but someone still needs to do all this work. 

If you think this is really worth it, please volunteer to do it. Nobody else will.


[*] (I like David Stone's proposal of -Wpadded-in-middle and -Wpadded-at-end, but whoever implements it gets to choose the names)
Comment 5 David Stone 2015-04-24 01:55:27 UTC
After thinking about this some more, we are not answering the question that splitting it into two warnings is really trying to get at.

The first, and most important is not "Is there padding in the middle of the structure", but "Can I rearrange my data members to save space?". -Wwasted-space might be a good name for this warning. I believe in all systems that gcc targets*, the optimal size can be achieved by arranging elements largest to smallest, so we could just compare the size of a theoretical struct with that arrangment and the size of the user's struct.

The second thing the user might wonder is "Do I have padding that I cannot resolve by rearranging". This warning can alert the user that a small change in the size of their data types (or possibly moving data into different structures) could have a greater-than-expected size savings. This is more like the current -Wpadded.

* A strange system with 4-byte, 3-byte, and 1-byte aligned types could have a more efficient representation by following every 3 with a 1. I am unsure if this is actually valid according to the C or C++ standard. As long as all of the systems just have power-of-two alignment, the largest to smallest works.
Comment 6 Trass3r 2019-05-30 06:09:57 UTC
(In reply to Manuel López-Ibáñez from comment #4)
> This is quite easy to implement.

It's not as trivial as one might think.
There's some copy-paste code to disable the flag in various places (instead of handling it inside if possible).


$ find -name '*.c' | xargs fgrep -nC2 warn_padded
./gcc/config/spu/spu.c-3959-  /* We know this is being padded and we want it too.  It is an internal
./gcc/config/spu/spu.c-3960-     type so hide the warnings from the user. */
./gcc/config/spu/spu.c:3961:  owp = warn_padded;
./gcc/config/spu/spu.c:3962:  warn_padded = false;
./gcc/config/spu/spu.c-3963-
./gcc/config/spu/spu.c-3964-  layout_type (record);
./gcc/config/spu/spu.c-3965-
./gcc/config/spu/spu.c:3966:  warn_padded = owp;
./gcc/config/spu/spu.c-3967-
./gcc/config/spu/spu.c-3968-  /* The correct type is an array type of one element.  */
--
./gcc/config/tilegx/tilegx.c-340-  /* We know this is being padded and we want it too.  It is an
./gcc/config/tilegx/tilegx.c-341-     internal type so hide the warnings from the user.  */
./gcc/config/tilegx/tilegx.c:342:  owp = warn_padded;
./gcc/config/tilegx/tilegx.c:343:  warn_padded = false;
./gcc/config/tilegx/tilegx.c-344-
./gcc/config/tilegx/tilegx.c-345-  layout_type (record);
./gcc/config/tilegx/tilegx.c-346-
./gcc/config/tilegx/tilegx.c:347:  warn_padded = owp;
./gcc/config/tilegx/tilegx.c-348-
./gcc/config/tilegx/tilegx.c-349-  /* The correct type is an array type of one element.  */
--
./gcc/config/tilepro/tilepro.c-292-  /* We know this is being padded and we want it too.  It is an
./gcc/config/tilepro/tilepro.c-293-     internal type so hide the warnings from the user.  */
./gcc/config/tilepro/tilepro.c:294:  owp = warn_padded;
./gcc/config/tilepro/tilepro.c:295:  warn_padded = false;
./gcc/config/tilepro/tilepro.c-296-
./gcc/config/tilepro/tilepro.c-297-  layout_type (record);
./gcc/config/tilepro/tilepro.c-298-
./gcc/config/tilepro/tilepro.c:299:  warn_padded = owp;
./gcc/config/tilepro/tilepro.c-300-
./gcc/config/tilepro/tilepro.c-301-  /* The correct type is an array type of one element.  */
--
./gcc/fortran/trans-io.c-223-  /* -Wpadded warnings on these artificially created structures are not
./gcc/fortran/trans-io.c-224-     helpful; suppress them. */
./gcc/fortran/trans-io.c:225:  int save_warn_padded = warn_padded;
./gcc/fortran/trans-io.c:226:  warn_padded = 0;
./gcc/fortran/trans-io.c-227-  gfc_finish_type (t);
./gcc/fortran/trans-io.c:228:  warn_padded = save_warn_padded;
./gcc/fortran/trans-io.c-229-  st_parameter[ptype].type = t;
./gcc/fortran/trans-io.c-230-}
./gcc/tree-nested.c-3197-      /* In some cases the frame type will trigger the -Wpadded warning.
./gcc/tree-nested.c-3198-        This is not helpful; suppress it. */
./gcc/tree-nested.c:3199:      int save_warn_padded = warn_padded;
./gcc/tree-nested.c:3200:      warn_padded = 0;
./gcc/tree-nested.c-3201-      layout_type (root->frame_type);
./gcc/tree-nested.c:3202:      warn_padded = save_warn_padded;
./gcc/tree-nested.c-3203-      layout_decl (root->frame_decl, 0);
./gcc/tree-nested.c-3204-
Comment 7 Trass3r 2019-05-30 06:43:16 UTC
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68901
is an example of missed -Wpadded suppression.
Comment 8 Manuel López-Ibáñez 2019-05-30 09:12:58 UTC
(In reply to krux from comment #6)
> (In reply to Manuel López-Ibáñez from comment #4)
> > This is quite easy to implement.
> 
> It's not as trivial as one might think.
> There's some copy-paste code to disable the flag in various places (instead
> of handling it inside if possible).

You can still have a global -Wpadded that implies the two new warning options and only warn, for example, if warn_padded && warn_packed_size are both true.

Even better would be to mark these types as internal/ARTIFICIAL, look for all places where OPT_Wpadded is used and, if not already done, avoid warning for anything internal /ARTIFICIAL, then remove this hack.

This should require no major surgery in the compiler nor any deep knowledge about the code.
Comment 9 David Stone 2019-12-22 20:01:53 UTC
It might further be worth giving the "you can rearrange to save sapce" option two warning levels. The highest level would warn for all cases where rearranging can reduce size, and the lowest level would warn for all cases where rearranging only the private data members can reduce size. This is a potentially important point because rearranging public / protected data members can affect the API of your type by changing how it interacts with structured bindings, and, if it is also an aggregate, aggregate construction.

The important new consideration that has the potential for a third warning option is the handling of empty types. It could be useful to have a warning that alerts the user that marking a data member with [[no_unique_address]] would reduce the size of their structure. A potential name for this is -Wempty-data-member-wastes-space or -Wmissing-no-unique-address.

Cross posted to the equivalent clang bug report: https://bugs.llvm.org/show_bug.cgi?id=22442#c5
Comment 10 Eric Gallager 2019-12-22 21:52:21 UTC
(In reply to Aaron S. Kurland from comment #1)
> I just realized that my original message was referring to the wrong option.
> I meant: -Wpadded
> 
> I am therefore requesting two new options:
> 
> -Wpadded-element and -Wpadded-structure
> 
> Sorry for the confusion.

Confirmed, I have wanted a split like this as well.

(In reply to Manuel López-Ibáñez from comment #4)
> 
> [*] (I like David Stone's proposal of -Wpadded-in-middle and
> -Wpadded-at-end, but whoever implements it gets to choose the names)

Those are good name suggestions too.