Message ID | c55778c092112802ae897889ec4b839b4d058a8f.camel@mengyan1223.wang |
---|---|
State | New |
Headers | show |
Series | mips: Ignore zero width bitfields in arguments and issue -Wpsabi warning about C zero-width bit-field ABI changes [PR102024] | expand |
On Fri, Apr 01, 2022 at 12:27:45AM +0800, Xi Ruoyao wrote: > --- a/gcc/config/mips/mips.cc > +++ b/gcc/config/mips/mips.cc > @@ -6042,11 +6042,26 @@ mips_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) > for (i = 0; i < info.reg_words; i++) > { > rtx reg; > + int has_zero_width_bf_abi_change = 0; If something has just 0/1 value, perhaps better use bool and false/true for the values? > for (; field; field = DECL_CHAIN (field)) > - if (TREE_CODE (field) == FIELD_DECL > - && int_bit_position (field) >= bitpos) > - break; > + { > + if (TREE_CODE (field) != FIELD_DECL) > + continue; > + > + /* Ignore zero-width bit-fields. And, if the ignored > + field is not from C++, it may be an ABI change. */ > + if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field)) > + continue; While the above is only about zero width bit-fields from the C++ FE, > + if (integer_zerop (DECL_SIZE (field))) this matches both zero width bitfields and zero sized structures and zero length arrays. While I believe the same arguments as for zero width bitfields apply for those and it is interesting to see what say LLVM does with those (see the compat testsuite change I've posted today), either the diagnostics should be worded so that it covers both, or this could be a 0/1/2 value flag or enum which then decides how to word the diagnostics. Including the _bf in the name is misleading. > + { > + has_zero_width_bf_abi_change = 1; > + continue; > + } > + static const char *url = > + CHANGES_ROOT_URL > + "gcc-12/changes.html#zero_width_bitfields"; Formatting guidelines say that the = should go on the next line. > + inform (input_location, > + "the ABI for passing a value containing " > + "zero-width bit-fields before an adjacent " > + "64-bit floating-point field was retconned " > + "in GCC %{12.1%}", url); Not a native speaker, but retconned seems weird and would be better to match the wording in other targets. > + last_reported_type_uid = uid; > + } > + } > > XVECEXP (ret, 0, i) > = gen_rtx_EXPR_LIST (VOIDmode, reg, Jakub
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index 3284cf71f6f..5d1637e7b2f 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -6042,11 +6042,26 @@ mips_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) for (i = 0; i < info.reg_words; i++) { rtx reg; + int has_zero_width_bf_abi_change = 0; for (; field; field = DECL_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL - && int_bit_position (field) >= bitpos) - break; + { + if (TREE_CODE (field) != FIELD_DECL) + continue; + + /* Ignore zero-width bit-fields. And, if the ignored + field is not from C++, it may be an ABI change. */ + if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field)) + continue; + if (integer_zerop (DECL_SIZE (field))) + { + has_zero_width_bf_abi_change = 1; + continue; + } + + if (int_bit_position (field) >= bitpos) + break; + } if (field && int_bit_position (field) == bitpos @@ -6054,7 +6069,29 @@ mips_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD) reg = gen_rtx_REG (DFmode, FP_ARG_FIRST + info.reg_offset + i); else - reg = gen_rtx_REG (DImode, GP_ARG_FIRST + info.reg_offset + i); + { + reg = gen_rtx_REG (DImode, + GP_ARG_FIRST + info.reg_offset + i); + has_zero_width_bf_abi_change = 0; + } + + if (has_zero_width_bf_abi_change && warn_psabi) + { + static unsigned last_reported_type_uid; + unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (arg.type)); + if (uid != last_reported_type_uid) + { + static const char *url = + CHANGES_ROOT_URL + "gcc-12/changes.html#zero_width_bitfields"; + inform (input_location, + "the ABI for passing a value containing " + "zero-width bit-fields before an adjacent " + "64-bit floating-point field was retconned " + "in GCC %{12.1%}", url); + last_reported_type_uid = uid; + } + } XVECEXP (ret, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, reg, diff --git a/gcc/testsuite/gcc.target/mips/pr102024.c b/gcc/testsuite/gcc.target/mips/pr102024.c new file mode 100644 index 00000000000..c45d01315d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/pr102024.c @@ -0,0 +1,20 @@ +// PR target/102024 +// { dg-do compile } +// { dg-options "-mabi=64 -mhard-float" } +// { dg-final { scan-assembler "\\\$f12" } } + +struct foo +{ + int : 0; + double a; +}; + +extern void func(struct foo); + +void +pass_foo(void) +{ + struct foo test; + test.a = 114; + func(test); // { dg-message "the ABI for passing a value containing zero-width bit-fields before an adjacent 64-bit floating-point field was retconned in GCC 12.1" } +}