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
This commit is contained in:
parent
c32bd276c6
commit
00aa1fa221
26 changed files with 809 additions and 14 deletions
|
@ -1,3 +1,27 @@
|
|||
2017-08-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
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.
|
||||
|
||||
2017-08-17 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR bootstrap/81864
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2017-08-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
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.
|
||||
|
||||
2017-08-14 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/81117
|
||||
|
|
|
@ -89,6 +89,8 @@ static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
|
|||
static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_section_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
|
||||
int, bool *);
|
||||
static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
|
||||
static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
|
||||
static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
|
||||
|
@ -217,6 +219,9 @@ const struct attribute_spec c_common_attribute_table[] =
|
|||
handle_section_attribute, false },
|
||||
{ "aligned", 0, 1, false, false, false,
|
||||
handle_aligned_attribute, false },
|
||||
{ "warn_if_not_aligned", 0, 1, false, false, false,
|
||||
handle_warn_if_not_aligned_attribute,
|
||||
false },
|
||||
{ "weak", 0, 0, true, false, false,
|
||||
handle_weak_attribute, false },
|
||||
{ "noplt", 0, 0, true, false, false,
|
||||
|
@ -1666,12 +1671,13 @@ check_cxx_fundamental_alignment_constraints (tree node,
|
|||
return !alignment_too_large_p;
|
||||
}
|
||||
|
||||
/* Handle a "aligned" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
/* Common codes shared by handle_warn_if_not_aligned_attribute and
|
||||
handle_aligned_attribute. */
|
||||
|
||||
static tree
|
||||
handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
|
||||
int flags, bool *no_add_attrs)
|
||||
common_handle_aligned_attribute (tree *node, tree args, int flags,
|
||||
bool *no_add_attrs,
|
||||
bool warn_if_not_aligned_p)
|
||||
{
|
||||
tree decl = NULL_TREE;
|
||||
tree *type = NULL;
|
||||
|
@ -1720,8 +1726,16 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
|
|||
else
|
||||
*type = build_variant_type_copy (*type);
|
||||
|
||||
SET_TYPE_ALIGN (*type, (1U << i) * BITS_PER_UNIT);
|
||||
TYPE_USER_ALIGN (*type) = 1;
|
||||
if (warn_if_not_aligned_p)
|
||||
{
|
||||
SET_TYPE_WARN_IF_NOT_ALIGN (*type, (1U << i) * BITS_PER_UNIT);
|
||||
warn_if_not_aligned_p = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_TYPE_ALIGN (*type, (1U << i) * BITS_PER_UNIT);
|
||||
TYPE_USER_ALIGN (*type) = 1;
|
||||
}
|
||||
}
|
||||
else if (! VAR_OR_FUNCTION_DECL_P (decl)
|
||||
&& TREE_CODE (decl) != FIELD_DECL)
|
||||
|
@ -1754,13 +1768,54 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
|
|||
}
|
||||
else
|
||||
{
|
||||
SET_DECL_ALIGN (decl, (1U << i) * BITS_PER_UNIT);
|
||||
DECL_USER_ALIGN (decl) = 1;
|
||||
if (warn_if_not_aligned_p)
|
||||
{
|
||||
if (TREE_CODE (decl) == FIELD_DECL && !DECL_INITIAL (decl))
|
||||
{
|
||||
SET_DECL_WARN_IF_NOT_ALIGN (decl, (1U << i) * BITS_PER_UNIT);
|
||||
warn_if_not_aligned_p = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_DECL_ALIGN (decl, (1U << i) * BITS_PER_UNIT);
|
||||
DECL_USER_ALIGN (decl) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (warn_if_not_aligned_p)
|
||||
{
|
||||
error ("%<warn_if_not_aligned%> may not be specified for %q+D",
|
||||
decl);
|
||||
*no_add_attrs = true;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "aligned" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
|
||||
int flags, bool *no_add_attrs)
|
||||
{
|
||||
return common_handle_aligned_attribute (node, args, flags,
|
||||
no_add_attrs, false);
|
||||
}
|
||||
|
||||
/* Handle a "warn_if_not_aligned" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_warn_if_not_aligned_attribute (tree *node, tree ARG_UNUSED (name),
|
||||
tree args, int flags,
|
||||
bool *no_add_attrs)
|
||||
{
|
||||
return common_handle_aligned_attribute (node, args, flags,
|
||||
no_add_attrs, true);
|
||||
}
|
||||
|
||||
/* Handle a "weak" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
|
|
|
@ -579,6 +579,10 @@ Wformat-truncation=
|
|||
C ObjC C++ ObjC++ Joined RejectNegative UInteger Var(warn_format_trunc) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 1, 0) IntegerRange(0, 2)
|
||||
Warn about calls to snprintf and similar functions that truncate output.
|
||||
|
||||
Wif-not-aligned
|
||||
C ObjC C++ ObjC++ Var(warn_if_not_aligned) Init(1) Warning
|
||||
Warn when the field in a struct is not aligned.
|
||||
|
||||
Wignored-qualifiers
|
||||
C C++ Var(warn_ignored_qualifiers) Warning EnabledBy(Wextra)
|
||||
Warn whenever type qualifiers are ignored.
|
||||
|
@ -710,6 +714,10 @@ Wnamespaces
|
|||
C++ ObjC++ Var(warn_namespaces) Warning
|
||||
Warn on namespace definition.
|
||||
|
||||
Wpacked-not-aligned
|
||||
C ObjC C++ ObjC++ Var(warn_packed_not_aligned) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
|
||||
Warn when fields in a struct with the packed attribute are misaligned.
|
||||
|
||||
Wsized-deallocation
|
||||
C++ ObjC++ Var(warn_sized_deallocation) Warning EnabledBy(Wextra)
|
||||
Warn about missing sized deallocation functions.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2017-08-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
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.
|
||||
|
||||
2017-08-14 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/81117
|
||||
|
|
|
@ -2383,6 +2383,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
|||
SET_DECL_ALIGN (newdecl, DECL_ALIGN (olddecl));
|
||||
DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
|
||||
}
|
||||
if (DECL_WARN_IF_NOT_ALIGN (olddecl)
|
||||
> DECL_WARN_IF_NOT_ALIGN (newdecl))
|
||||
SET_DECL_WARN_IF_NOT_ALIGN (newdecl,
|
||||
DECL_WARN_IF_NOT_ALIGN (olddecl));
|
||||
}
|
||||
|
||||
/* Keep the old rtl since we can safely use it. */
|
||||
|
@ -5395,6 +5399,13 @@ check_bitfield_type_and_width (location_t loc, tree *type, tree *width,
|
|||
*type = unsigned_type_node;
|
||||
}
|
||||
|
||||
if (TYPE_WARN_IF_NOT_ALIGN (*type))
|
||||
{
|
||||
error_at (loc, "cannot declare bit-field %qs with %<warn_if_not_aligned%> type",
|
||||
name);
|
||||
*type = unsigned_type_node;
|
||||
}
|
||||
|
||||
type_mv = TYPE_MAIN_VARIANT (*type);
|
||||
if (!in_system_header_at (input_location)
|
||||
&& type_mv != integer_type_node
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2017-08-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
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.
|
||||
|
||||
2017-08-17 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* cp-tree.def (TEMPLATE_TEMPLATE_PARM): Remove stale comment.
|
||||
|
|
|
@ -2510,6 +2510,10 @@ next_arg:;
|
|||
DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
|
||||
}
|
||||
DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
|
||||
if (DECL_WARN_IF_NOT_ALIGN (olddecl)
|
||||
> DECL_WARN_IF_NOT_ALIGN (newdecl))
|
||||
SET_DECL_WARN_IF_NOT_ALIGN (newdecl,
|
||||
DECL_WARN_IF_NOT_ALIGN (olddecl));
|
||||
if (TREE_CODE (newdecl) == FIELD_DECL)
|
||||
DECL_PACKED (olddecl) = DECL_PACKED (newdecl);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -5780,6 +5780,41 @@ alignment. See your linker documentation for further information.
|
|||
The @code{aligned} attribute can also be used for functions
|
||||
(@pxref{Common Function Attributes}.)
|
||||
|
||||
@cindex @code{warn_if_not_aligned} variable attribute
|
||||
@item warn_if_not_aligned (@var{alignment})
|
||||
This attribute specifies a threshold for the structure field, measured
|
||||
in bytes. If the structure field is aligned below the threshold, a
|
||||
warning will be issued. For example, the declaration:
|
||||
|
||||
@smallexample
|
||||
struct foo
|
||||
@{
|
||||
int i1;
|
||||
int i2;
|
||||
unsigned long long x __attribute__((warn_if_not_aligned(16)));
|
||||
@};
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
causes the compiler to issue an warning on @code{struct foo}, like
|
||||
@samp{warning: alignment 8 of 'struct foo' is less than 16}.
|
||||
The compiler also issues a warning, like @samp{warning: 'x' offset
|
||||
8 in 'struct foo' isn't aligned to 16}, when the structure field has
|
||||
the misaligned offset:
|
||||
|
||||
@smallexample
|
||||
struct foo
|
||||
@{
|
||||
int i1;
|
||||
int i2;
|
||||
unsigned long long x __attribute__((warn_if_not_aligned(16)));
|
||||
@} __attribute__((aligned(16)));
|
||||
@end smallexample
|
||||
|
||||
This warning can be disabled by @option{-Wno-if-not-aligned}.
|
||||
The @code{warn_if_not_aligned} attribute can also be used for types
|
||||
(@pxref{Common Type Attributes}.)
|
||||
|
||||
@item cleanup (@var{cleanup_function})
|
||||
@cindex @code{cleanup} variable attribute
|
||||
The @code{cleanup} attribute runs a function when the variable goes
|
||||
|
@ -6657,6 +6692,58 @@ alignment. See your linker documentation for further information.
|
|||
The @code{aligned} attribute can only increase alignment. Alignment
|
||||
can be decreased by specifying the @code{packed} attribute. See below.
|
||||
|
||||
@cindex @code{warn_if_not_aligned} type attribute
|
||||
@item warn_if_not_aligned (@var{alignment})
|
||||
This attribute specifies a threshold for the structure field, measured
|
||||
in bytes. If the structure field is aligned below the threshold, a
|
||||
warning will be issued. For example, the declaration:
|
||||
|
||||
@smallexample
|
||||
typedef unsigned long long __u64
|
||||
__attribute__((aligned(4),warn_if_not_aligned(8)));
|
||||
|
||||
struct foo
|
||||
@{
|
||||
int i1;
|
||||
int i2;
|
||||
__u64 x;
|
||||
@};
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
causes the compiler to issue an warning on @code{struct foo}, like
|
||||
@samp{warning: alignment 4 of 'struct foo' is less than 8}.
|
||||
It is used to define @code{struct foo} in such a way that
|
||||
@code{struct foo} has the same layout and the structure field @code{x}
|
||||
has the same alignment when @code{__u64} is aligned at either 4 or
|
||||
8 bytes. Align @code{struct foo} to 8 bytes:
|
||||
|
||||
@smallexample
|
||||
struct foo
|
||||
@{
|
||||
int i1;
|
||||
int i2;
|
||||
__u64 x;
|
||||
@} __attribute__((aligned(8)));
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
silences the warning. The compiler also issues a warning, like
|
||||
@samp{warning: 'x' offset 12 in 'struct foo' isn't aligned to 8},
|
||||
when the structure field has the misaligned offset:
|
||||
|
||||
@smallexample
|
||||
struct foo
|
||||
@{
|
||||
int i1;
|
||||
int i2;
|
||||
int i3;
|
||||
__u64 x;
|
||||
@} __attribute__((aligned(8)));
|
||||
@end smallexample
|
||||
|
||||
This warning can be disabled by @option{-Wno-if-not-aligned}.
|
||||
|
||||
@item bnd_variable_size
|
||||
@cindex @code{bnd_variable_size} type attribute
|
||||
@cindex Pointer Bounds Checker attributes
|
||||
|
|
|
@ -284,6 +284,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-Wformat-security -Wformat-signedness -Wformat-truncation=@var{n} @gol
|
||||
-Wformat-y2k -Wframe-address @gol
|
||||
-Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol
|
||||
-Wif-not-aligned @gol
|
||||
-Wignored-qualifiers -Wignored-attributes -Wincompatible-pointer-types @gol
|
||||
-Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n} @gol
|
||||
-Wimplicit-function-declaration -Wimplicit-int @gol
|
||||
|
@ -298,7 +299,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-Wnormalized=@r{[}none@r{|}id@r{|}nfc@r{|}nfkc@r{]} @gol
|
||||
-Wnull-dereference -Wodr -Wno-overflow -Wopenmp-simd @gol
|
||||
-Woverride-init-side-effects -Woverlength-strings @gol
|
||||
-Wpacked -Wpacked-bitfield-compat -Wpadded @gol
|
||||
-Wpacked -Wpacked-bitfield-compat -Wpacked-not-aligned -Wpadded @gol
|
||||
-Wparentheses -Wno-pedantic-ms-format @gol
|
||||
-Wplacement-new -Wplacement-new=@var{n} @gol
|
||||
-Wpointer-arith -Wpointer-compare -Wno-pointer-to-int-cast @gol
|
||||
|
@ -4427,6 +4428,13 @@ switch (cond)
|
|||
|
||||
The @option{-Wimplicit-fallthrough=3} warning is enabled by @option{-Wextra}.
|
||||
|
||||
@item -Wif-not-aligned @r{(C, C++, Objective-C and Objective-C++ only)}
|
||||
@opindex Wif-not-aligned
|
||||
@opindex Wno-if-not-aligned
|
||||
Control if warning triggered by the @code{warn_if_not_aligned} attribute
|
||||
should be issued. This is is enabled by default.
|
||||
Use @option{-Wno-if-not-aligned} to disable it.
|
||||
|
||||
@item -Wignored-qualifiers @r{(C and C++ only)}
|
||||
@opindex Wignored-qualifiers
|
||||
@opindex Wno-ignored-qualifiers
|
||||
|
@ -6520,6 +6528,25 @@ struct foo
|
|||
This warning is enabled by default. Use
|
||||
@option{-Wno-packed-bitfield-compat} to disable this warning.
|
||||
|
||||
@item -Wpacked-not-aligned @r{(C, C++, Objective-C and Objective-C++ only)}
|
||||
@opindex Wpacked-not-aligned
|
||||
@opindex Wno-packed-not-aligned
|
||||
Warn if a structure field with explicitly specified alignment in a
|
||||
packed struct or union is misaligned. For example, a warning will
|
||||
be issued on @code{struct S}, like, @code{warning: alignment 1 of
|
||||
'struct S' is less than 8}, in this code:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
struct __attribute__ ((aligned (8))) S8 @{ char a[8]; @};
|
||||
struct __attribute__ ((packed)) S @{
|
||||
struct S8 s8;
|
||||
@};
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
This warning is enabled by @option{-Wall}.
|
||||
|
||||
@item -Wpadded
|
||||
@opindex Wpadded
|
||||
@opindex Wno-padded
|
||||
|
|
|
@ -458,7 +458,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
|
|||
if (DECL_USER_ALIGN (node))
|
||||
fprintf (file, " user");
|
||||
|
||||
fprintf (file, " align:%d", DECL_ALIGN (node));
|
||||
fprintf (file, " align:%d warn_if_not_align:%d",
|
||||
DECL_ALIGN (node), DECL_WARN_IF_NOT_ALIGN (node));
|
||||
if (code == FIELD_DECL)
|
||||
fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
|
||||
DECL_OFFSET_ALIGN (node));
|
||||
|
@ -603,8 +604,10 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
|
|||
if (TYPE_USER_ALIGN (node))
|
||||
fprintf (file, " user");
|
||||
|
||||
fprintf (file, " align:%d symtab:%d alias-set " HOST_WIDE_INT_PRINT_DEC,
|
||||
TYPE_ALIGN (node), TYPE_SYMTAB_ADDRESS (node),
|
||||
fprintf (file, " align:%d warn_if_not_align:%d symtab:%d alias-set "
|
||||
HOST_WIDE_INT_PRINT_DEC,
|
||||
TYPE_ALIGN (node), TYPE_WARN_IF_NOT_ALIGN (node),
|
||||
TYPE_SYMTAB_ADDRESS (node),
|
||||
(HOST_WIDE_INT) TYPE_ALIAS_SET (node));
|
||||
|
||||
if (TYPE_STRUCTURAL_EQUALITY_P (node))
|
||||
|
|
|
@ -570,6 +570,8 @@ do_type_align (tree type, tree decl)
|
|||
if (TREE_CODE (decl) == FIELD_DECL)
|
||||
DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
|
||||
}
|
||||
if (TYPE_WARN_IF_NOT_ALIGN (type) > DECL_WARN_IF_NOT_ALIGN (decl))
|
||||
SET_DECL_WARN_IF_NOT_ALIGN (decl, TYPE_WARN_IF_NOT_ALIGN (type));
|
||||
}
|
||||
|
||||
/* Set the size, mode and alignment of a ..._DECL node.
|
||||
|
@ -1074,6 +1076,57 @@ update_alignment_for_field (record_layout_info rli, tree field,
|
|||
return desired_align;
|
||||
}
|
||||
|
||||
/* Issue a warning if the record alignment, RECORD_ALIGN, is less than
|
||||
the field alignment of FIELD or FIELD isn't aligned. */
|
||||
|
||||
static void
|
||||
handle_warn_if_not_align (tree field, unsigned int record_align)
|
||||
{
|
||||
tree type = TREE_TYPE (field);
|
||||
|
||||
if (type == error_mark_node)
|
||||
return;
|
||||
|
||||
unsigned int warn_if_not_align = 0;
|
||||
|
||||
int opt_w = 0;
|
||||
|
||||
if (warn_if_not_aligned)
|
||||
{
|
||||
warn_if_not_align = DECL_WARN_IF_NOT_ALIGN (field);
|
||||
if (!warn_if_not_align)
|
||||
warn_if_not_align = TYPE_WARN_IF_NOT_ALIGN (type);
|
||||
if (warn_if_not_align)
|
||||
opt_w = OPT_Wif_not_aligned;
|
||||
}
|
||||
|
||||
if (!warn_if_not_align
|
||||
&& warn_packed_not_aligned
|
||||
&& TYPE_USER_ALIGN (type))
|
||||
{
|
||||
warn_if_not_align = TYPE_ALIGN (type);
|
||||
opt_w = OPT_Wpacked_not_aligned;
|
||||
}
|
||||
|
||||
if (!warn_if_not_align)
|
||||
return;
|
||||
|
||||
tree context = DECL_CONTEXT (field);
|
||||
|
||||
warn_if_not_align /= BITS_PER_UNIT;
|
||||
record_align /= BITS_PER_UNIT;
|
||||
if ((record_align % warn_if_not_align) != 0)
|
||||
warning (opt_w, "alignment %u of %qT is less than %u",
|
||||
record_align, context, warn_if_not_align);
|
||||
|
||||
unsigned HOST_WIDE_INT off
|
||||
= (tree_to_uhwi (DECL_FIELD_OFFSET (field))
|
||||
+ tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field)) / BITS_PER_UNIT);
|
||||
if ((off % warn_if_not_align) != 0)
|
||||
warning (opt_w, "%q+D offset %wu in %qT isn't aligned to %u",
|
||||
field, off, context, warn_if_not_align);
|
||||
}
|
||||
|
||||
/* Called from place_field to handle unions. */
|
||||
|
||||
static void
|
||||
|
@ -1084,6 +1137,7 @@ place_union_field (record_layout_info rli, tree field)
|
|||
DECL_FIELD_OFFSET (field) = size_zero_node;
|
||||
DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
|
||||
SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
|
||||
handle_warn_if_not_align (field, rli->record_align);
|
||||
|
||||
/* If this is an ERROR_MARK return *after* having set the
|
||||
field at the start of the union. This helps when parsing
|
||||
|
@ -1169,6 +1223,7 @@ place_field (record_layout_info rli, tree field)
|
|||
DECL_FIELD_OFFSET (field) = rli->offset;
|
||||
DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
|
||||
SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
|
||||
handle_warn_if_not_align (field, rli->record_align);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1290,6 +1345,9 @@ place_field (record_layout_info rli, tree field)
|
|||
|
||||
if (! DECL_PACKED (field))
|
||||
TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
|
||||
|
||||
SET_TYPE_WARN_IF_NOT_ALIGN (rli->t,
|
||||
TYPE_WARN_IF_NOT_ALIGN (type));
|
||||
}
|
||||
|
||||
#ifdef BITFIELD_NBYTES_LIMITED
|
||||
|
@ -1328,6 +1386,8 @@ place_field (record_layout_info rli, tree field)
|
|||
rli->bitpos = round_up (rli->bitpos, type_align);
|
||||
|
||||
TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
|
||||
SET_TYPE_WARN_IF_NOT_ALIGN (rli->t,
|
||||
TYPE_WARN_IF_NOT_ALIGN (type));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1478,6 +1538,7 @@ place_field (record_layout_info rli, tree field)
|
|||
DECL_FIELD_OFFSET (field) = rli->offset;
|
||||
DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
|
||||
SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
|
||||
handle_warn_if_not_align (field, rli->record_align);
|
||||
|
||||
/* Evaluate nonconstant offsets only once, either now or as soon as safe. */
|
||||
if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST)
|
||||
|
@ -2088,6 +2149,8 @@ finish_builtin_struct (tree type, const char *name, tree fields,
|
|||
{
|
||||
SET_TYPE_ALIGN (type, TYPE_ALIGN (align_type));
|
||||
TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
|
||||
SET_TYPE_WARN_IF_NOT_ALIGN (type,
|
||||
TYPE_WARN_IF_NOT_ALIGN (align_type));
|
||||
}
|
||||
|
||||
layout_type (type);
|
||||
|
@ -2324,6 +2387,9 @@ layout_type (tree type)
|
|||
align = MAX (align, TYPE_ALIGN (type));
|
||||
else
|
||||
TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
|
||||
if (!TYPE_WARN_IF_NOT_ALIGN (type))
|
||||
SET_TYPE_WARN_IF_NOT_ALIGN (type,
|
||||
TYPE_WARN_IF_NOT_ALIGN (element));
|
||||
#ifdef ROUND_TYPE_ALIGN
|
||||
align = ROUND_TYPE_ALIGN (type, align, BITS_PER_UNIT);
|
||||
#else
|
||||
|
|
|
@ -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.
|
||||
|
|
81
gcc/testsuite/c-c++-common/pr53037-5.c
Normal file
81
gcc/testsuite/c-c++-common/pr53037-5.c
Normal file
|
@ -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)));
|
81
gcc/testsuite/g++.dg/pr53037-1.C
Normal file
81
gcc/testsuite/g++.dg/pr53037-1.C
Normal file
|
@ -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)));
|
37
gcc/testsuite/g++.dg/pr53037-2.C
Normal file
37
gcc/testsuite/g++.dg/pr53037-2.C
Normal file
|
@ -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;
|
||||
};
|
37
gcc/testsuite/g++.dg/pr53037-3.C
Normal file
37
gcc/testsuite/g++.dg/pr53037-3.C
Normal file
|
@ -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;
|
||||
};
|
24
gcc/testsuite/g++.dg/pr53037-4.C
Normal file
24
gcc/testsuite/g++.dg/pr53037-4.C
Normal file
|
@ -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" } */
|
||||
};
|
81
gcc/testsuite/gcc.dg/pr53037-1.c
Normal file
81
gcc/testsuite/gcc.dg/pr53037-1.c
Normal file
|
@ -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)));
|
37
gcc/testsuite/gcc.dg/pr53037-2.c
Normal file
37
gcc/testsuite/gcc.dg/pr53037-2.c
Normal file
|
@ -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;
|
||||
};
|
37
gcc/testsuite/gcc.dg/pr53037-3.c
Normal file
37
gcc/testsuite/gcc.dg/pr53037-3.c
Normal file
|
@ -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;
|
||||
};
|
24
gcc/testsuite/gcc.dg/pr53037-4.c
Normal file
24
gcc/testsuite/gcc.dg/pr53037-4.c
Normal file
|
@ -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" } */
|
||||
};
|
|
@ -1523,8 +1523,9 @@ struct GTY(()) tree_type_common {
|
|||
so we need to store the value 32 (not 31, as we need the zero
|
||||
as well), hence six bits. */
|
||||
unsigned align : 6;
|
||||
unsigned warn_if_not_align : 6;
|
||||
unsigned typeless_storage : 1;
|
||||
unsigned spare : 24;
|
||||
unsigned spare : 18;
|
||||
|
||||
alias_set_type alias_set;
|
||||
tree pointer_to;
|
||||
|
@ -1631,7 +1632,11 @@ struct GTY(()) tree_decl_common {
|
|||
/* DECL_ALIGN. It should have the same size as TYPE_ALIGN. */
|
||||
unsigned int align : 6;
|
||||
|
||||
/* 20 bits unused. */
|
||||
/* DECL_WARN_IF_NOT_ALIGN. It should have the same size as
|
||||
TYPE_WARN_IF_NOT_ALIGN. */
|
||||
unsigned int warn_if_not_align : 6;
|
||||
|
||||
/* 14 bits unused. */
|
||||
|
||||
/* UID for points-to sets, stable over copying from inlining. */
|
||||
unsigned int pt_uid;
|
||||
|
|
|
@ -7505,6 +7505,7 @@ build_range_type_1 (tree type, tree lowval, tree highval, bool shared)
|
|||
TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (type);
|
||||
SET_TYPE_ALIGN (itype, TYPE_ALIGN (type));
|
||||
TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (type);
|
||||
SET_TYPE_WARN_IF_NOT_ALIGN (itype, TYPE_WARN_IF_NOT_ALIGN (type));
|
||||
|
||||
if (!shared)
|
||||
return itype;
|
||||
|
|
20
gcc/tree.h
20
gcc/tree.h
|
@ -1919,6 +1919,16 @@ extern machine_mode element_mode (const_tree t);
|
|||
/* The alignment for NODE, in bytes. */
|
||||
#define TYPE_ALIGN_UNIT(NODE) (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
|
||||
|
||||
/* The minimum alignment necessary for objects of this type without
|
||||
warning. The value is an int, measured in bits. */
|
||||
#define TYPE_WARN_IF_NOT_ALIGN(NODE) \
|
||||
(TYPE_CHECK (NODE)->type_common.warn_if_not_align \
|
||||
? ((unsigned)1) << ((NODE)->type_common.warn_if_not_align - 1) : 0)
|
||||
|
||||
/* Specify that TYPE_WARN_IF_NOT_ALIGN(NODE) is X. */
|
||||
#define SET_TYPE_WARN_IF_NOT_ALIGN(NODE, X) \
|
||||
(TYPE_CHECK (NODE)->type_common.warn_if_not_align = ffs_hwi (X))
|
||||
|
||||
/* If your language allows you to declare types, and you want debug info
|
||||
for them, then you need to generate corresponding TYPE_DECL nodes.
|
||||
These "stub" TYPE_DECL nodes have no name, and simply point at the
|
||||
|
@ -2371,6 +2381,16 @@ extern machine_mode element_mode (const_tree t);
|
|||
#define SET_DECL_ALIGN(NODE, X) \
|
||||
(DECL_COMMON_CHECK (NODE)->decl_common.align = ffs_hwi (X))
|
||||
|
||||
/* The minimum alignment necessary for the datum, in bits, without
|
||||
warning. */
|
||||
#define DECL_WARN_IF_NOT_ALIGN(NODE) \
|
||||
(DECL_COMMON_CHECK (NODE)->decl_common.warn_if_not_align \
|
||||
? ((unsigned)1) << ((NODE)->decl_common.warn_if_not_align - 1) : 0)
|
||||
|
||||
/* Specify that DECL_WARN_IF_NOT_ALIGN(NODE) is X. */
|
||||
#define SET_DECL_WARN_IF_NOT_ALIGN(NODE, X) \
|
||||
(DECL_COMMON_CHECK (NODE)->decl_common.warn_if_not_align = ffs_hwi (X))
|
||||
|
||||
/* The alignment of NODE, in bytes. */
|
||||
#define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT)
|
||||
/* Set if the alignment of this DECL has been set by the user, for
|
||||
|
|
Loading…
Add table
Reference in a new issue