diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f8d30cab8d4cf2a34dada168f31b3390ee4cd53..dca869b74a12798d350c1e3985526d2704cd0748 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-03-29 H.J. Lu <hongjiu.lu@intel.com> + + PR target/39545 + * config/i386/i386.c (classify_argument): Ignore flexible array + member in struct and warn ABI change. + 2009-03-29 H.J. Lu <hongjiu.lu@intel.com> * config/i386/i386-protos.h (ix86_agi_dependent): New. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 4a6d601ce45e7f81b0e4628a5961b5a8b2ce1034..3dec02f3acd7e4c45f1f3121a638ed8165b0bc51 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4942,8 +4942,30 @@ classify_argument (enum machine_mode mode, const_tree type, } else { - num = classify_argument (TYPE_MODE (TREE_TYPE (field)), - TREE_TYPE (field), subclasses, + type = TREE_TYPE (field); + + /* Flexible array member is ignored. */ + if (TYPE_MODE (type) == BLKmode + && TREE_CODE (type) == ARRAY_TYPE + && TYPE_SIZE (type) == NULL_TREE + && TYPE_DOMAIN (type) != NULL_TREE + && (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) + == NULL_TREE)) + { + static bool warned; + + if (!warned && warn_psabi) + { + warned = true; + inform (input_location, + "The ABI of passing struct with" + " a flexible array member has" + " changed in GCC 4.4"); + } + continue; + } + num = classify_argument (TYPE_MODE (type), type, + subclasses, (int_bit_position (field) + bit_offset) % 256); if (!num) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2f60726156537d267efddbcf8fcd13e28298e50e..7546a2d33a0baa5fec5522c8087e124f85926e88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2009-03-29 H.J. Lu <hongjiu.lu@intel.com> + + PR target/39545 + * gcc.c-torture/compile/pr16566-2.c: Add -Wno-psabi for x86-64. + + * gcc.target/i386/pr39545-1.c: New. + * gcc.target/i386/pr39545-2.c: Likewise. + + * gcc.target/x86_64/abi/test_passing_structs.c (flex1_struct): New. + (flex2_struct): Likewise. + (check_struct_passing7): Likewise. + (check_struct_passing8): Likewise. + (f1s): Likewise. + (f2s): Likewise. + (main): Call check_struct_passing7 and check_struct_passing8. + 2009-03-29 Richard Guenther <rguenther@suse.de> * gcc.c-torture/execute/20090113-1.c: New testcase. diff --git a/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c b/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c index c0036f0fc6458fc6586e68a477550c569797bd3a..2f7a10668a73da213518f8aab13b0334fd439cfe 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c @@ -1,5 +1,6 @@ /* ICE with flexible arrays in non-lvalue structures. Bug 16566 (comment #5). */ +/* { dg-options "-Wno-psabi" { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ struct A { diff --git a/gcc/testsuite/gcc.target/i386/pr39545-1.c b/gcc/testsuite/gcc.target/i386/pr39545-1.c new file mode 100644 index 0000000000000000000000000000000000000000..62bc33fa21d59dc2c82576508e97ecc90b183481 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr39545-1.c @@ -0,0 +1,24 @@ +/* PR target/39545 */ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2" } */ + +struct flex +{ + int i; + int flex []; +}; + +int +foo (struct flex s) /* { dg-message "note: The ABI of passing struct with a flexible array member has changed in GCC 4.4" } */ +{ + return s.i; +} + +struct flex +bar (int x) +{ + struct flex s; + s.i = x; + return s; +} diff --git a/gcc/testsuite/gcc.target/i386/pr39545-2.c b/gcc/testsuite/gcc.target/i386/pr39545-2.c new file mode 100644 index 0000000000000000000000000000000000000000..143c3827fd6c762b174fb9a284ba8c38e0288b11 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr39545-2.c @@ -0,0 +1,18 @@ +/* PR target/39545 */ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2" } */ + +struct flex +{ + int i; + int flex []; +}; + +struct flex +foo (int x) +{ /* { dg-message "note: The ABI of passing struct with a flexible array member has changed in GCC 4.4" } */ + struct flex s; + s.i = x; + return s; +} diff --git a/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c b/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c index 3ce0db14652e4ed6f579a3b9ed3fdf3830d2a55f..68eca53a2e431952ee443c8eaaef2c6130764bf7 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c +++ b/gcc/testsuite/gcc.target/x86_64/abi/test_passing_structs.c @@ -92,6 +92,33 @@ check_struct_passing6 (struct m128_2_struct ms ATTRIBUTE_UNUSED) } #endif +struct flex1_struct +{ + long i; + long flex[]; +}; + +struct flex2_struct +{ + long i; + long flex[0]; +}; + +void +check_struct_passing7 (struct flex1_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +void +check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +static struct flex1_struct f1s = { 60, { } }; +static struct flex2_struct f2s = { 61, { } }; + int main (void) { @@ -146,5 +173,17 @@ main (void) WRAP_CALL (check_struct_passing6)(m128_2s); #endif + clear_struct_registers; + iregs.I0 = f1s.i; + num_iregs = 1; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing7)(f1s); + + clear_struct_registers; + iregs.I0 = f2s.i; + num_iregs = 1; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing8)(f2s); + return 0; }