Add warn_if_not_aligned attribute

Programming / Compilers / GCC - hjl [138bc75d-0d04-0410-961f-82ee72b054a4] - 18 August 2017 05:38 EDT

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): Copy TYPE_WARN_IF_NOT_ALIGN.
- 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 DECL_WARN_IF_NOT_ALIGN. (check_bitfield_type_and_width): Don't allow bit-field with warn_if_not_aligned type.

gcc/cp/

PR c/53037
- decl.c (duplicate_decls): Also merge DECL_WARN_IF_NOT_ALIGN.
- decl2.c (grokbitfield): Don't allow bit-field with warn_if_not_aligned type.

gcc/testsuite/

PR c/53037
- c-c++-common/pr53037-5.c: New test.
- g++.dg/pr53037-1.C: Likewise.
- g++.dg/pr53037-2.C: Likewise.
- g++.dg/pr53037-3.C: Likewise.
- g++.dg/pr53037-4.C: Likewise.
- gcc.dg/pr53037-1.c: Likewise.
- gcc.dg/pr53037-2.c: Likewise.
- gcc.dg/pr53037-3.c: Likewise.
- gcc.dg/pr53037-4.c: Likewise.

4bec728 Add warn_if_not_aligned attribute
gcc/ChangeLog | 24 ++++++++++
gcc/c-family/ChangeLog | 11 +++++
gcc/c-family/c-attribs.c | 71 +++++++++++++++++++++++----
gcc/c-family/c.opt | 8 ++++
gcc/c/ChangeLog | 7 +++
gcc/c/c-decl.c | 11 +++++
gcc/cp/ChangeLog | 7 +++
gcc/cp/decl.c | 4 ++
gcc/cp/decl2.c | 7 +++
gcc/doc/extend.texi | 87 ++++++++++++++++++++++++++++++++++
gcc/doc/invoke.texi | 29 +++++++++++-
gcc/print-tree.c | 9 ++--
gcc/stor-layout.c | 66 ++++++++++++++++++++++++++
gcc/testsuite/ChangeLog | 13 +++++
gcc/testsuite/c-c++-common/pr53037-5.c | 81 +++++++++++++++++++++++++++++++
gcc/testsuite/g++.dg/pr53037-1.C | 81 +++++++++++++++++++++++++++++++
gcc/testsuite/g++.dg/pr53037-2.C | 37 +++++++++++++++
gcc/testsuite/g++.dg/pr53037-3.C | 37 +++++++++++++++
gcc/testsuite/g++.dg/pr53037-4.C | 24 ++++++++++
gcc/testsuite/gcc.dg/pr53037-1.c | 81 +++++++++++++++++++++++++++++++
gcc/testsuite/gcc.dg/pr53037-2.c | 37 +++++++++++++++
gcc/testsuite/gcc.dg/pr53037-3.c | 37 +++++++++++++++
gcc/testsuite/gcc.dg/pr53037-4.c | 24 ++++++++++
gcc/tree-core.h | 9 +++-
gcc/tree.c | 1 +
gcc/tree.h | 20 ++++++++
26 files changed, 809 insertions(+), 14 deletions(-)

Upstream: gcc.gnu.org


  • Share