diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2017-08-18 09:38:38 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2017-08-18 02:38:38 -0700 |
commit | 00aa1fa221744dc57f6c6cea8baa669b732d1101 (patch) | |
tree | 1dbbe35f67ab9fc825f52d4cbe56fbeed0afafa3 /gcc/testsuite | |
parent | c32bd276c68f5089b7e8ee58a8bc85c9bd543455 (diff) | |
download | gcc-00aa1fa221744dc57f6c6cea8baa669b732d1101.zip gcc-00aa1fa221744dc57f6c6cea8baa669b732d1101.tar.gz gcc-00aa1fa221744dc57f6c6cea8baa669b732d1101.tar.bz2 |
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
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr53037-5.c | 81 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr53037-1.C | 81 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr53037-2.C | 37 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr53037-3.C | 37 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr53037-4.C | 24 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr53037-1.c | 81 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr53037-2.c | 37 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr53037-3.c | 37 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr53037-4.c | 24 |
10 files changed, 452 insertions, 0 deletions
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 <hongjiu.lu@intel.com> + + 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 <bergner@vnet.ibm.com> * 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" } */ +}; |