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
This commit is contained in:
parent
55de4f08f4
commit
c6e4cc53e5
@ -1,3 +1,8 @@
|
|||||||
|
2003-07-16 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
* c-common.c (handle_packed_attribute): Don't pack a struct via a
|
||||||
|
typedef. Propagate packedness from a main variant.
|
||||||
|
|
||||||
2003-07-22 Nathanael Nerode <neroden@gcc.gnu.org>
|
2003-07-22 Nathanael Nerode <neroden@gcc.gnu.org>
|
||||||
|
|
||||||
* Makefile.in (install-common): Add dependency on installdirs.
|
* Makefile.in (install-common): Add dependency on installdirs.
|
||||||
|
@ -4534,25 +4534,33 @@ static tree
|
|||||||
handle_packed_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
|
handle_packed_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
|
||||||
int flags, bool *no_add_attrs)
|
int flags, bool *no_add_attrs)
|
||||||
{
|
{
|
||||||
tree *type = NULL;
|
if (TYPE_P (*node))
|
||||||
if (DECL_P (*node))
|
|
||||||
{
|
|
||||||
if (TREE_CODE (*node) == TYPE_DECL)
|
|
||||||
type = &TREE_TYPE (*node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
type = node;
|
|
||||||
|
|
||||||
if (type)
|
|
||||||
{
|
{
|
||||||
if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
|
if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
|
||||||
*type = build_type_copy (*type);
|
*node = build_type_copy (*node);
|
||||||
TYPE_PACKED (*type) = 1;
|
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)
|
else if (TREE_CODE (*node) == FIELD_DECL)
|
||||||
DECL_PACKED (*node) = 1;
|
DECL_PACKED (*node) = 1;
|
||||||
/* We can't set DECL_PACKED for a VAR_DECL, because the bit is
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
* gcc.dg/pack-test-3.c: New test.
|
||||||
|
|
||||||
2003-07-21 Janis Johnson <janis187@us.ibm.com>
|
2003-07-21 Janis Johnson <janis187@us.ibm.com>
|
||||||
|
|
||||||
* lib/compat.exp: Handle dg-options per source file.
|
* lib/compat.exp: Handle dg-options per source file.
|
||||||
|
44
gcc/testsuite/gcc.dg/pack-test-3.c
Normal file
44
gcc/testsuite/gcc.dg/pack-test-3.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* { dg-do compile } */
|
||||||
|
|
||||||
|
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
Contributed by Nathan Sidwell 15 Jul 2003 <nathan@codesourcery.com> */
|
||||||
|
|
||||||
|
/* you should not be able to pack a typedef to a struct, only the
|
||||||
|
underlying struct can be packed. */
|
||||||
|
|
||||||
|
/* ok */
|
||||||
|
struct u1
|
||||||
|
{
|
||||||
|
char field1;
|
||||||
|
short field2;
|
||||||
|
int field3;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ok */
|
||||||
|
typedef struct p1 {
|
||||||
|
char field1;
|
||||||
|
short field2;
|
||||||
|
int field3;
|
||||||
|
} __attribute__ ((packed)) p1_t1;
|
||||||
|
|
||||||
|
/* ok */
|
||||||
|
typedef struct __attribute__ ((packed)) p2 {
|
||||||
|
char field1;
|
||||||
|
short field2;
|
||||||
|
int field3;
|
||||||
|
} p2_t1;
|
||||||
|
|
||||||
|
int ary1[sizeof (struct p1) == sizeof (p1_t1) ? 1 : -1];
|
||||||
|
int ary2[sizeof (struct p2) == sizeof (p2_t1) ? 1 : -1];
|
||||||
|
int ary3[sizeof (struct p1) == sizeof (struct p2) ? 1 : -1];
|
||||||
|
|
||||||
|
/* not ok */
|
||||||
|
typedef struct u1 __attribute__ ((packed)) u1_t1; /* { dg-warning "attribute ignored" "" }*/
|
||||||
|
typedef struct u1 u1_t2 __attribute__ ((packed)); /* { dg-warning "attribute ignored" "" }*/
|
||||||
|
|
||||||
|
typedef struct p3 {
|
||||||
|
char field1;
|
||||||
|
short field2;
|
||||||
|
int field3;
|
||||||
|
} p3_t1 __attribute__ ((packed)); /* { dg-warning "attribute ignored" "" }*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user