TYPE_ARG_TYPES of type variants must compare equal, according to verify_type, but adjust_at_calls_type didn't preserve this invariant.
Adjust the main type variant and propagate TYPE_ARG_TYPES to all variants. While at that, also adjust the canonical type and its variants, and then verify_type. Regstrapped on x86_64-linux-gnu. Ok to install? for gcc/ChangeLog PR c/115848 * ipa-strub.cc (pass_ipa_strub::adjust_at_calls_type_main): Rename from... (pass_ipa_strub::adjust_at_calls_type): ... this. Preserve TYPE_ARG_TYPES across all variants. Adjust TYPE_CANONICAL and verify_type. for gcc/testsuite/ChangeLog PR c/115848 * c-c++-common/strub-pr115848.c: New. * c-c++-common/strub-pr115848-b.c: New. --- gcc/ipa-strub.cc | 41 ++++++++++++++++++++++++- gcc/testsuite/c-c++-common/strub-pr115848-b.c | 6 ++++ gcc/testsuite/c-c++-common/strub-pr115848.c | 8 +++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/strub-pr115848-b.c create mode 100644 gcc/testsuite/c-c++-common/strub-pr115848.c diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc index 8fa7bdf530023..15d91c994bf8f 100644 --- a/gcc/ipa-strub.cc +++ b/gcc/ipa-strub.cc @@ -1891,6 +1891,7 @@ public: #undef DEF_IDENT + static inline int adjust_at_calls_type_main (tree); static inline int adjust_at_calls_type (tree); static inline void adjust_at_calls_call (cgraph_edge *, int, tree); static inline void adjust_at_calls_calls (cgraph_node *); @@ -2348,15 +2349,51 @@ strub_watermark_parm (tree fndecl) gcc_unreachable (); } +/* Adjust a STRUB_AT_CALLS function TYPE and all its variants, + preserving TYPE_ARG_TYPES identity, adding a watermark pointer if + it hasn't been added yet. Return the named argument count. */ + +int +pass_ipa_strub::adjust_at_calls_type (tree type) +{ + gcc_checking_assert (same_strub_mode_in_variants_p (type)); + + tree tmain = TYPE_MAIN_VARIANT (type); + tree orig_types = TYPE_ARG_TYPES (tmain); + gcc_checking_assert (TYPE_ARG_TYPES (type) == orig_types); + int named_args = adjust_at_calls_type_main (tmain); + tree mod_types = TYPE_ARG_TYPES (tmain); + + if (mod_types != orig_types) + for (tree other = TYPE_NEXT_VARIANT (tmain); + other != NULL_TREE; other = TYPE_NEXT_VARIANT (other)) + { + gcc_checking_assert (TYPE_ARG_TYPES (other) == orig_types); + TYPE_ARG_TYPES (other) = mod_types; + } + + if (TYPE_CANONICAL (type) + && TYPE_MAIN_VARIANT (TYPE_CANONICAL (type)) != tmain) + { + int ret = adjust_at_calls_type (TYPE_CANONICAL (type)); + gcc_checking_assert (named_args == ret); + } + + if (flag_checking) + verify_type (type); + + return named_args; +} + /* Adjust a STRUB_AT_CALLS function TYPE, adding a watermark pointer if it hasn't been added yet. Return the named argument count. */ int -pass_ipa_strub::adjust_at_calls_type (tree type) +pass_ipa_strub::adjust_at_calls_type_main (tree type) { int named_args = 0; - gcc_checking_assert (same_strub_mode_in_variants_p (type)); + gcc_checking_assert (TYPE_MAIN_VARIANT (type) == type); if (!TYPE_ARG_TYPES (type)) return named_args; diff --git a/gcc/testsuite/c-c++-common/strub-pr115848-b.c b/gcc/testsuite/c-c++-common/strub-pr115848-b.c new file mode 100644 index 0000000000000..9b9e134b3f41a --- /dev/null +++ b/gcc/testsuite/c-c++-common/strub-pr115848-b.c @@ -0,0 +1,6 @@ +/* { dg-skip-if part { *-*-* } } */ +void __attribute__((__strub__)) b(int, int) {} +void c(void); +int main() { + c(); +} diff --git a/gcc/testsuite/c-c++-common/strub-pr115848.c b/gcc/testsuite/c-c++-common/strub-pr115848.c new file mode 100644 index 0000000000000..1586540907213 --- /dev/null +++ b/gcc/testsuite/c-c++-common/strub-pr115848.c @@ -0,0 +1,8 @@ +/* { dg-do link } */ +/* { dg-require-effective-target lto } */ +/* { dg-options "-flto" } */ +/* { dg-additional-sources "strub-pr115848-b.c" } */ + +typedef void __attribute__((__strub__)) a(int, int); +a(b); +void c() { b(0, 0); } -- Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ Free Software Activist GNU Toolchain Engineer More tolerance and less prejudice are key for inclusion and diversity Excluding neuro-others for not behaving ""normal"" is *not* inclusive