From dde5ce541e3258276848aee85229a71c0e5f6965 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 28 Apr 2020 10:26:24 +0200 Subject: [PATCH] s390: -Wpsabi diagnostics for C++14 vs. C++17 ABI incompatibility on s390{,x} [PR94704] > We probably have to look into providing a -Wpsabi warning as well. So like this? 2020-04-28 Jakub Jelinek PR target/94704 * config/s390/s390.c (s390_function_arg_vector, s390_function_arg_float): Emit -Wpsabi diagnostics if the ABI changed. --- gcc/ChangeLog | 6 +++++ gcc/config/s390/s390.c | 54 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe1ddac16eb..bb017f2de2b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-04-28 Jakub Jelinek + + PR target/94704 + * config/s390/s390.c (s390_function_arg_vector, + s390_function_arg_float): Emit -Wpsabi diagnostics if the ABI changed. + 2020-04-28 Richard Sandiford PR tree-optimization/94727 diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index e282bb8c666..50994bc413d 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -11911,16 +11911,22 @@ s390_function_arg_vector (machine_mode mode, const_tree type) /* The ABI says that record types with a single member are treated just like that member would be. */ + bool cxx17_empty_base_seen = false; while (TREE_CODE (type) == RECORD_TYPE) { tree field, single = NULL_TREE; for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { - if (TREE_CODE (field) != FIELD_DECL - || cxx17_empty_base_field_p (field)) + if (TREE_CODE (field) != FIELD_DECL) continue; + if (cxx17_empty_base_field_p (field)) + { + cxx17_empty_base_seen = true; + continue; + } + if (single == NULL_TREE) single = TREE_TYPE (field); else @@ -11940,7 +11946,22 @@ s390_function_arg_vector (machine_mode mode, const_tree type) } } - return VECTOR_TYPE_P (type); + if (!VECTOR_TYPE_P (type)) + return false; + + if (warn_psabi && cxx17_empty_base_seen) + { + static unsigned last_reported_type_uid; + unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (type)); + if (uid != last_reported_type_uid) + { + last_reported_type_uid = uid; + inform (input_location, "parameter passing for argument of type " + "%qT when C++17 is enabled changed to match " + "C++14 in GCC 10.1", type); + } + } + return true; } /* Return true if a function argument of type TYPE and mode MODE @@ -11962,15 +11983,20 @@ s390_function_arg_float (machine_mode mode, const_tree type) /* The ABI says that record types with a single member are treated just like that member would be. */ + bool cxx17_empty_base_seen = false; while (TREE_CODE (type) == RECORD_TYPE) { tree field, single = NULL_TREE; for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { - if (TREE_CODE (field) != FIELD_DECL - || cxx17_empty_base_field_p (field)) + if (TREE_CODE (field) != FIELD_DECL) continue; + if (cxx17_empty_base_field_p (field)) + { + cxx17_empty_base_seen = true; + continue; + } if (single == NULL_TREE) single = TREE_TYPE (field); @@ -11984,7 +12010,23 @@ s390_function_arg_float (machine_mode mode, const_tree type) type = single; } - return TREE_CODE (type) == REAL_TYPE; + if (TREE_CODE (type) != REAL_TYPE) + return false; + + if (warn_psabi && cxx17_empty_base_seen) + { + static unsigned last_reported_type_uid; + unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (type)); + if (uid != last_reported_type_uid) + { + last_reported_type_uid = uid; + inform (input_location, "parameter passing for argument of type " + "%qT when C++17 is enabled changed to match " + "C++14 in GCC 10.1", type); + } + } + + return true; } /* Return true if a function argument of type TYPE and mode MODE -- 2.30.2