diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 874920c2d93c..8ba806e23549 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-01-08 Douglas B Rupp + + * config/i386/i386.c (ix86_attribute_table): Add new attributes + ms_struct and gcc_struct. + (ix86_handle_struct_attribute): New function. + (ix86_ms_bitfield_layout_p): Update to take new attributes + into account. + * doc/extend.texi: Document new attributes. + * testsuite/gcc.dg/bf-ms-attrib.c: New test. + 2003-01-08 Danny Smith PR optimization/8750 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 64618f83cf4c..682fa897d0b0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -870,6 +870,7 @@ static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool * static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *)); static int ix86_value_regno PARAMS ((enum machine_mode)); static bool ix86_ms_bitfield_layout_p PARAMS ((tree)); +static tree ix86_handle_struct_attribute PARAMS ((tree *, tree, tree, int, bool *)); static int extended_reg_mentioned_1 PARAMS ((rtx *, void *)); #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION) @@ -1456,6 +1457,8 @@ const struct attribute_spec ix86_attribute_table[] = { "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute }, { "shared", 0, 0, true, false, false, ix86_handle_shared_attribute }, #endif + { "ms_struct", 0, 0, false, false, false, ix86_handle_struct_attribute }, + { "gcc_struct", 0, 0, false, false, false, ix86_handle_struct_attribute }, { NULL, 0, 0, false, false, false, NULL } }; @@ -14531,11 +14534,52 @@ x86_order_regs_for_local_alloc () #define TARGET_USE_MS_BITFIELD_LAYOUT 0 #endif +/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in + struct attribute_spec.handler. */ +static tree +ix86_handle_struct_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args ATTRIBUTE_UNUSED; + int flags ATTRIBUTE_UNUSED; + 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 && (TREE_CODE (*type) == RECORD_TYPE + || TREE_CODE (*type) == UNION_TYPE))) + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + else if ((is_attribute_p ("ms_struct", name) + && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type))) + || ((is_attribute_p ("gcc_struct", name) + && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type))))) + { + warning ("`%s' incompatible attribute ignored", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + static bool ix86_ms_bitfield_layout_p (record_type) - tree record_type ATTRIBUTE_UNUSED; + tree record_type; { - return TARGET_USE_MS_BITFIELD_LAYOUT; + return (TARGET_USE_MS_BITFIELD_LAYOUT && + !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type))) + || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)); } /* Returns an expression indicating where the this parameter is diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index cb7a0a3ee9fd..26817b0ca66c 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3212,6 +3212,26 @@ Medium and large model objects may live anywhere in the 32-bit address space (the compiler will generate @code{seth/add3} instructions to load their addresses). +@subsection i386 Variable Attributes + +Two attributes are currently defined for i386 configurations: +@code{ms_struct} and @code{gcc_struct} + +@item ms_struct +@itemx gcc_struct +@cindex @code{ms_struct} +@cindex @code{gcc_struct} + +If @code{packed} is used on a structure, or if bit-fields are used +it may be that the Microsoft ABI packs them differently +than GCC would normally pack them. Particularly when moving packed +data between functions compiled with GCC and the native Microsoft compiler +(either via function call or as data in a file), it may be necessary to access +either format. + +Currently @option{-m[no-]ms-bitfields} is provided for the Windows X86 +compilers to match the native Microsoft compiler. + @end table To specify multiple attributes, separate them by commas within the @@ -3471,6 +3491,26 @@ If you replaced @code{short_a} with @code{short} in the variable declaration, the above program would abort when compiled with @option{-fstrict-aliasing}, which is on by default at @option{-O2} or above in recent GCC versions. + +@subsection i386 Type Attributes + +Two attributes are currently defined for i386 configurations: +@code{ms_struct} and @code{gcc_struct} + +@item ms_struct +@itemx gcc_struct +@cindex @code{ms_struct} +@cindex @code{gcc_struct} + +If @code{packed} is used on a structure, or if bit-fields are used +it may be that the Microsoft ABI packs them differently +than GCC would normally pack them. Particularly when moving packed +data between functions compiled with GCC and the native Microsoft compiler +(either via function call or as data in a file), it may be necessary to access +either format. + +Currently @option{-m[no-]ms-bitfields} is provided for the Windows X86 +compilers to match the native Microsoft compiler. @end table To specify multiple attributes, separate them by commas within the diff --git a/gcc/testsuite/gcc.dg/bf-ms-attrib.c b/gcc/testsuite/gcc.dg/bf-ms-attrib.c new file mode 100644 index 000000000000..5633476c0e70 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bf-ms-attrib.c @@ -0,0 +1,39 @@ +/* bf-ms-attrib.c */ +/* Adapted from Donn Terry testcase + posted to GCC-patches + http://gcc.gnu.org/ml/gcc-patches/2000-08/msg00577.html */ + +/* { dg-do run { target *-*-interix* } } */ + +/* We don't want the default "pedantic-errors" in this case, since we're + testing nonstandard stuff to begin with. */ +/* { dg-options "-ansi" } */ + +#include + +struct one_gcc { + int d; + unsigned char a; + unsigned short b:7; + char c; +} __attribute__((__gcc_struct__)) ; + + +struct one_ms { + int d; + unsigned char a; + unsigned short b:7; + char c; +} __attribute__((__ms_struct__)); + + +main() + { + /* As long as the sizes are as expected, we know attributes are working. + bf-ms-layout.c makes sure the right thing happens when the attribute + is on. */ + if (sizeof(struct one_ms) != 12) + abort(); + if (sizeof(struct one_gcc) != 8) + abort(); + }