From 00aa1fa221744dc57f6c6cea8baa669b732d1101 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 18 Aug 2017 09:38:38 +0000 Subject: Add warn_if_not_aligned attribute 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): 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. From-SVN: r251180 --- 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 ++++++++++ 10 files changed, 452 insertions(+) create mode 100644 gcc/testsuite/c-c++-common/pr53037-5.c create mode 100644 gcc/testsuite/g++.dg/pr53037-1.C create mode 100644 gcc/testsuite/g++.dg/pr53037-2.C create mode 100644 gcc/testsuite/g++.dg/pr53037-3.C create mode 100644 gcc/testsuite/g++.dg/pr53037-4.C create mode 100644 gcc/testsuite/gcc.dg/pr53037-1.c create mode 100644 gcc/testsuite/gcc.dg/pr53037-2.c create mode 100644 gcc/testsuite/gcc.dg/pr53037-3.c create mode 100644 gcc/testsuite/gcc.dg/pr53037-4.c (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9020770..bcf2495 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2017-08-18 H.J. Lu + + 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. + 2017-08-17 Peter Bergner * gcc.target/powerpc/p8vector-int128-1.c: Remove use of -mvsx-timode. diff --git a/gcc/testsuite/c-c++-common/pr53037-5.c b/gcc/testsuite/c-c++-common/pr53037-5.c new file mode 100644 index 0000000..97d54b1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr53037-5.c @@ -0,0 +1,81 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wno-if-not-aligned" } */ + +typedef unsigned long long __u64 + __attribute__((aligned(4),warn_if_not_aligned(8))); + +struct foo1 +{ + int i1; + int i2; + int i3; + __u64 x; +}; + +struct foo2 +{ + int i1; + int i2; + int i3; + __u64 x; +} __attribute__((aligned(8))); + +struct foo3 +{ + int i1; + int i3; + __u64 x; +}; + +struct foo4 +{ + int i1; + int i2; + __u64 x; +} __attribute__((aligned(8))); + +struct foo5 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +}; + +struct foo6 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +} __attribute__((aligned(16))); + +struct foo7 +{ + int i1; + int i2; + int i3; + int i4; + int x __attribute__((warn_if_not_aligned(16))); +} __attribute__((aligned(16))); + +union bar1 +{ + int i1; + __u64 x; +}; + +union bar2 +{ + int i1; + __u64 x; +} __attribute__((aligned(8))); + +union bar3 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +}; + +union bar4 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +} __attribute__((aligned(16))); diff --git a/gcc/testsuite/g++.dg/pr53037-1.C b/gcc/testsuite/g++.dg/pr53037-1.C new file mode 100644 index 0000000..a3d8f99 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr53037-1.C @@ -0,0 +1,81 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +typedef unsigned long long __u64 + __attribute__((aligned(4),warn_if_not_aligned(8))); + +struct foo1 /* { dg-warning "alignment 4 of 'foo1' is less than 8" } */ +{ + int i1; + int i2; + int i3; + __u64 x; /* { dg-warning "'foo1::x' offset 12 in 'foo1' isn't aligned to 8" } */ +}; + +struct foo2 +{ + int i1; + int i2; + int i3; + __u64 x; /* { dg-warning "'foo2::x' offset 12 in 'foo2' isn't aligned to 8" } */ +} __attribute__((aligned(8))); + +struct foo3 /* { dg-warning "alignment 4 of 'foo3' is less than 8" } */ +{ + int i1; + int i3; + __u64 x; +}; + +struct foo4 +{ + int i1; + int i2; + __u64 x; +} __attribute__((aligned(8))); + +struct foo5 /* { dg-warning "alignment 4 of 'foo5' is less than 16" } */ +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); /* { dg-warning "'foo5::x' offset 4 in 'foo5' isn't aligned to 16" } */ +}; + +struct foo6 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); /* { dg-warning "'foo6::x' offset 4 in 'foo6' isn't aligned to 16" } */ +} __attribute__((aligned(16))); + +struct foo7 +{ + int i1; + int i2; + int i3; + int i4; + int x __attribute__((warn_if_not_aligned(16))); +} __attribute__((aligned(16))); + +union bar1 /* { dg-warning "alignment 4 of 'bar1' is less than 8" } */ +{ + int i1; + __u64 x; +}; + +union bar2 +{ + int i1; + __u64 x; +} __attribute__((aligned(8))); + +union bar3 /* { dg-warning "alignment 4 of 'bar3' is less than 16" } */ +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +}; + +union bar4 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +} __attribute__((aligned(16))); diff --git a/gcc/testsuite/g++.dg/pr53037-2.C b/gcc/testsuite/g++.dg/pr53037-2.C new file mode 100644 index 0000000..e617f90 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr53037-2.C @@ -0,0 +1,37 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wpacked-not-aligned" } */ + +struct __attribute__ ((aligned (8))) S8 { char a[8]; }; +struct __attribute__ ((packed)) S1 { /* { dg-warning "alignment 1 of 'S1' is less than 8" } */ + struct S8 s8; +}; + +struct __attribute__ ((packed, aligned (8))) S2 { + struct S8 s8; +}; + +struct __attribute__ ((packed, aligned (8))) S3 { + int i1; + struct S8 s8; /* { dg-warning "'S3::s8' offset 4 in 'S3' isn't aligned to 8" } */ +}; + +struct __attribute__ ((packed, aligned (8))) S4 { + int i1; + int i2; + struct S8 s8; +}; + +struct __attribute__ ((packed)) S5 { + long long ll; +}; + +union __attribute__ ((packed)) U1 { /* { dg-warning "alignment 1 of 'U1' is less than 8" } */ + int i1; + struct S8 s8; +}; + +union __attribute__ ((packed, aligned (8))) U2 { + int i1; + struct S8 s8; +}; diff --git a/gcc/testsuite/g++.dg/pr53037-3.C b/gcc/testsuite/g++.dg/pr53037-3.C new file mode 100644 index 0000000..1ed6354 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr53037-3.C @@ -0,0 +1,37 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wall" } */ + +struct __attribute__ ((aligned (8))) S8 { char a[8]; }; +struct __attribute__ ((packed)) S1 { /* { dg-warning "alignment 1 of 'S1' is less than 8" } */ + struct S8 s8; +}; + +struct __attribute__ ((packed, aligned (8))) S2 { + struct S8 s8; +}; + +struct __attribute__ ((packed, aligned (8))) S3 { + int i1; + struct S8 s8; /* { dg-warning "'S3::s8' offset 4 in 'S3' isn't aligned to 8" } */ +}; + +struct __attribute__ ((packed, aligned (8))) S4 { + int i1; + int i2; + struct S8 s8; +}; + +struct __attribute__ ((packed)) S5 { + long long ll; +}; + +union __attribute__ ((packed)) U1 { /* { dg-warning "alignment 1 of 'U1' is less than 8" } */ + int i1; + struct S8 s8; +}; + +union __attribute__ ((packed, aligned (8))) U2 { + int i1; + struct S8 s8; +}; diff --git a/gcc/testsuite/g++.dg/pr53037-4.C b/gcc/testsuite/g++.dg/pr53037-4.C new file mode 100644 index 0000000..553dd9a --- /dev/null +++ b/gcc/testsuite/g++.dg/pr53037-4.C @@ -0,0 +1,24 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +int foo1 __attribute__((warn_if_not_aligned(8))); /* { dg-error "'warn_if_not_aligned' may not be specified for 'foo1'" } */ + +__attribute__((warn_if_not_aligned(8))) +void +foo2 (void) /* { dg-error "'warn_if_not_aligned' may not be specified for 'void foo2\\(\\)'" } */ +{ +} + +struct foo3 +{ + int i : 2 __attribute__((warn_if_not_aligned(8))); /* { dg-error "'warn_if_not_aligned' may not be specified for 'i'" } */ +}; + +typedef unsigned int __u32 + __attribute__((aligned(4),warn_if_not_aligned(8))); + +struct foo4 +{ + __u32 i : 2; /* { dg-error "cannot declare bit-field 'i' with 'warn_if_not_aligned' type" } */ +}; diff --git a/gcc/testsuite/gcc.dg/pr53037-1.c b/gcc/testsuite/gcc.dg/pr53037-1.c new file mode 100644 index 0000000..93af0a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr53037-1.c @@ -0,0 +1,81 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +typedef unsigned long long __u64 + __attribute__((aligned(4),warn_if_not_aligned(8))); + +struct foo1 +{ + int i1; + int i2; + int i3; + __u64 x; /* { dg-warning "'x' offset 12 in 'struct foo1' isn't aligned to 8" } */ +}; /* { dg-warning "alignment 4 of 'struct foo1' is less than 8" } */ + +struct foo2 +{ + int i1; + int i2; + int i3; + __u64 x; /* { dg-warning "'x' offset 12 in 'struct foo2' isn't aligned to 8" } */ +} __attribute__((aligned(8))); + +struct foo3 +{ + int i1; + int i3; + __u64 x; +}; /* { dg-warning "alignment 4 of 'struct foo3' is less than 8" } */ + +struct foo4 +{ + int i1; + int i2; + __u64 x; +} __attribute__((aligned(8))); + +struct foo5 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); /* { dg-warning "'x' offset 4 in 'struct foo5' isn't aligned to 16" } */ +}; /* { dg-warning "alignment 4 of 'struct foo5' is less than 16" } */ + +struct foo6 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); /* { dg-warning "'x' offset 4 in 'struct foo6' isn't aligned to 16" } */ +} __attribute__((aligned(16))); + +struct foo7 +{ + int i1; + int i2; + int i3; + int i4; + int x __attribute__((warn_if_not_aligned(16))); +} __attribute__((aligned(16))); + +union bar1 +{ + int i1; + __u64 x; +}; /* { dg-warning "alignment 4 of 'union bar1' is less than 8" } */ + +union bar2 +{ + int i1; + __u64 x; +} __attribute__((aligned(8))); + +union bar3 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +}; /* { dg-warning "alignment 4 of 'union bar3' is less than 16" } */ + +union bar4 +{ + int i1; + int x __attribute__((warn_if_not_aligned(16))); +} __attribute__((aligned(16))); diff --git a/gcc/testsuite/gcc.dg/pr53037-2.c b/gcc/testsuite/gcc.dg/pr53037-2.c new file mode 100644 index 0000000..f9934a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr53037-2.c @@ -0,0 +1,37 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wpacked-not-aligned" } */ + +struct __attribute__ ((aligned (8))) S8 { char a[8]; }; +struct __attribute__ ((packed)) S1 { + struct S8 s8; +}; /* { dg-warning "alignment 1 of 'struct S1' is less than 8" } */ + +struct __attribute__ ((packed, aligned (8))) S2 { + struct S8 s8; +}; + +struct __attribute__ ((packed, aligned (8))) S3 { + int i1; + struct S8 s8; /* { dg-warning "'s8' offset 4 in 'struct S3' isn't aligned to 8" } */ +}; + +struct __attribute__ ((packed, aligned (8))) S4 { + int i1; + int i2; + struct S8 s8; +}; + +struct __attribute__ ((packed)) S5 { + long long ll; +}; + +union __attribute__ ((packed)) U1 { + int i1; + struct S8 s8; +}; /* { dg-warning "alignment 1 of 'union U1' is less than 8" } */ + +union __attribute__ ((packed, aligned (8))) U2 { + int i1; + struct S8 s8; +}; diff --git a/gcc/testsuite/gcc.dg/pr53037-3.c b/gcc/testsuite/gcc.dg/pr53037-3.c new file mode 100644 index 0000000..fc69ae8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr53037-3.c @@ -0,0 +1,37 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wall" } */ + +struct __attribute__ ((aligned (8))) S8 { char a[8]; }; +struct __attribute__ ((packed)) S1 { + struct S8 s8; +}; /* { dg-warning "alignment 1 of 'struct S1' is less than 8" } */ + +struct __attribute__ ((packed, aligned (8))) S2 { + struct S8 s8; +}; + +struct __attribute__ ((packed, aligned (8))) S3 { + int i1; + struct S8 s8; /* { dg-warning "'s8' offset 4 in 'struct S3' isn't aligned to 8" } */ +}; + +struct __attribute__ ((packed, aligned (8))) S4 { + int i1; + int i2; + struct S8 s8; +}; + +struct __attribute__ ((packed)) S5 { + long long ll; +}; + +union __attribute__ ((packed)) U1 { + int i1; + struct S8 s8; +}; /* { dg-warning "alignment 1 of 'union U1' is less than 8" } */ + +union __attribute__ ((packed, aligned (8))) U2 { + int i1; + struct S8 s8; +}; diff --git a/gcc/testsuite/gcc.dg/pr53037-4.c b/gcc/testsuite/gcc.dg/pr53037-4.c new file mode 100644 index 0000000..feb3afa --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr53037-4.c @@ -0,0 +1,24 @@ +/* PR c/53037. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +int foo1 __attribute__((warn_if_not_aligned(8))); /* { dg-error "'warn_if_not_aligned' may not be specified for 'foo1'" } */ + +__attribute__((warn_if_not_aligned(8))) +void +foo2 (void) /* { dg-error "'warn_if_not_aligned' may not be specified for 'foo2'" } */ +{ +} + +struct foo3 +{ + int i : 2 __attribute__((warn_if_not_aligned(8))); /* { dg-error "'warn_if_not_aligned' may not be specified for 'i'" } */ +}; + +typedef unsigned int __u32 + __attribute__((aligned(4),warn_if_not_aligned(8))); + +struct foo4 +{ + __u32 i : 2; /* { dg-error "cannot declare bit-field 'i' with 'warn_if_not_aligned' type" } */ +}; -- cgit v1.1