diff options
author | Xi Ruoyao <xry111@mengyan1223.wang> | 2022-03-30 22:22:45 +0800 |
---|---|---|
committer | Xi Ruoyao <xry111@mengyan1223.wang> | 2022-04-01 22:37:43 +0800 |
commit | 0d4b97f1ee5213dffce107bc9f260a22fb23b4b1 (patch) | |
tree | e0ccf6bd93a74828f946a644daea4211e4683ffd /gcc/config/mips/mips.cc | |
parent | 86d8e0c0652ef5236a460b75c25e4f7093cc0651 (diff) | |
download | gcc-0d4b97f1ee5213dffce107bc9f260a22fb23b4b1.zip gcc-0d4b97f1ee5213dffce107bc9f260a22fb23b4b1.tar.gz gcc-0d4b97f1ee5213dffce107bc9f260a22fb23b4b1.tar.bz2 |
mips: Emit psabi diagnostic for return values affected by C++ zero-width bit-field ABI change [PR 102024]
gcc/
PR target/102024
* config/mips/mips.cc (mips_fpr_return_fields): Detect C++
zero-width bit-fields and set up an indicator.
(mips_return_in_msb): Adapt for mips_fpr_return_fields change.
(mips_function_value_1): Diagnose when the presense of a C++
zero-width bit-field changes function returning in GCC 12.
gcc/testsuite/
PR target/102024
* g++.target/mips/mips.exp: New test supporting file.
* g++.target/mips/pr102024.C: New test.
Diffstat (limited to 'gcc/config/mips/mips.cc')
-rw-r--r-- | gcc/config/mips/mips.cc | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index 91e1e96..83860b5 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -6274,10 +6274,17 @@ mips_callee_copies (cumulative_args_t, const function_arg_info &arg) For n32 & n64, a structure with one or two fields is returned in floating-point registers as long as every field has a floating-point - type. */ + type. + + The C++ FE used to remove zero-width bit-fields in GCC 11 and earlier. + To make a proper diagnostic, this function will set + HAS_CXX_ZERO_WIDTH_BF to true once a C++ zero-width bit-field shows up, + and then ignore it. Then the caller can determine if this zero-width + bit-field will make a difference and emit a -Wpsabi inform. */ static int -mips_fpr_return_fields (const_tree valtype, tree *fields) +mips_fpr_return_fields (const_tree valtype, tree *fields, + bool *has_cxx_zero_width_bf) { tree field; int i; @@ -6294,6 +6301,12 @@ mips_fpr_return_fields (const_tree valtype, tree *fields) if (TREE_CODE (field) != FIELD_DECL) continue; + if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field)) + { + *has_cxx_zero_width_bf = true; + continue; + } + if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (field))) return 0; @@ -6318,12 +6331,14 @@ mips_fpr_return_fields (const_tree valtype, tree *fields) static bool mips_return_in_msb (const_tree valtype) { - tree fields[2]; + if (!TARGET_NEWABI || !TARGET_BIG_ENDIAN || !AGGREGATE_TYPE_P (valtype)) + return false; - return (TARGET_NEWABI - && TARGET_BIG_ENDIAN - && AGGREGATE_TYPE_P (valtype) - && mips_fpr_return_fields (valtype, fields) == 0); + tree fields[2]; + bool has_cxx_zero_width_bf = false; + return (mips_fpr_return_fields (valtype, fields, + &has_cxx_zero_width_bf) == 0 + || has_cxx_zero_width_bf); } /* Return true if the function return value MODE will get returned in a @@ -6418,8 +6433,35 @@ mips_function_value_1 (const_tree valtype, const_tree fn_decl_or_type, return values, promote the mode here too. */ mode = promote_function_mode (valtype, mode, &unsigned_p, func, 1); + bool has_cxx_zero_width_bf = false; + int use_fpr = mips_fpr_return_fields (valtype, fields, + &has_cxx_zero_width_bf); + if (TARGET_HARD_FLOAT + && warn_psabi + && has_cxx_zero_width_bf + && use_fpr != 0) + { + static unsigned last_reported_type_uid; + unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (valtype)); + 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 returning a value containing " + "zero-width bit-fields but otherwise an aggregate " + "with only one or two floating-point fields was " + "changed in GCC %{12.1%}", url); + last_reported_type_uid = uid; + } + } + + if (has_cxx_zero_width_bf) + use_fpr = 0; + /* Handle structures whose fields are returned in $f0/$f2. */ - switch (mips_fpr_return_fields (valtype, fields)) + switch (use_fpr) { case 1: return mips_return_fpr_single (mode, |