aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2017-08-18 09:38:38 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2017-08-18 02:38:38 -0700
commit00aa1fa221744dc57f6c6cea8baa669b732d1101 (patch)
tree1dbbe35f67ab9fc825f52d4cbe56fbeed0afafa3 /gcc/cp/decl2.c
parentc32bd276c68f5089b7e8ee58a8bc85c9bd543455 (diff)
downloadgcc-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/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 37393a1..66d206e 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1008,6 +1008,13 @@ grokbitfield (const cp_declarator *declarator,
return NULL_TREE;
}
+ if (width && TYPE_WARN_IF_NOT_ALIGN (TREE_TYPE (value)))
+ {
+ error ("cannot declare bit-field %qD with %<warn_if_not_aligned%> type",
+ DECL_NAME (value));
+ return NULL_TREE;
+ }
+
if (DECL_IN_AGGR_P (value))
{
error ("%qD is already defined in the class %qT", value,