aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2003-07-22 09:26:01 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2003-07-22 09:26:01 +0000
commitc6e4cc53e53de0f671b715bfb83f37dbf73aaf2f (patch)
tree99496b3fc47148edf71566fe7c4b58da3579195c /gcc/c-common.c
parent55de4f08f41b19bc0a72c7e0676b53d9c4b0a9fd (diff)
downloadgcc-c6e4cc53e53de0f671b715bfb83f37dbf73aaf2f.zip
gcc-c6e4cc53e53de0f671b715bfb83f37dbf73aaf2f.tar.gz
gcc-c6e4cc53e53de0f671b715bfb83f37dbf73aaf2f.tar.bz2
c-common.c (handle_packed_attribute): Don't pack a struct via a typedef.
* c-common.c (handle_packed_attribute): Don't pack a struct via a typedef. Propagate packedness from a main variant. testsuite: * gcc.dg/pack-test-3.c: New test. From-SVN: r69668
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index c33e632..b5d6651 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4534,25 +4534,33 @@ static tree
handle_packed_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
int flags, bool *no_add_attrs)
{
- tree *type = NULL;
- if (DECL_P (*node))
- {
- if (TREE_CODE (*node) == TYPE_DECL)
- type = &TREE_TYPE (*node);
- }
- else
- type = node;
-
- if (type)
+ if (TYPE_P (*node))
{
if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
- *type = build_type_copy (*type);
- TYPE_PACKED (*type) = 1;
+ *node = build_type_copy (*node);
+ TYPE_PACKED (*node) = 1;
+ if (TYPE_MAIN_VARIANT (*node) == *node)
+ {
+ /* If it is the main variant, then pack the other variants
+ too. This happens in,
+
+ struct Foo {
+ struct Foo const *ptr; // creates a variant w/o packed flag
+ } __ attribute__((packed)); // packs it now.
+ */
+ tree probe;
+
+ for (probe = *node; probe; probe = TYPE_NEXT_VARIANT (probe))
+ TYPE_PACKED (probe) = 1;
+ }
+
}
else if (TREE_CODE (*node) == FIELD_DECL)
DECL_PACKED (*node) = 1;
/* We can't set DECL_PACKED for a VAR_DECL, because the bit is
- used for DECL_REGISTER. It wouldn't mean anything anyway. */
+ used for DECL_REGISTER. It wouldn't mean anything anyway.
+ We can't set DECL_PACKED on the type of a TYPE_DECL, because
+ that changes what the typedef is typing. */
else
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));