From: Martin Liska Date: Mon, 2 Dec 2019 11:18:31 +0000 (+0100) Subject: Refactor IPA devirt a bit. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=74fee04253a5007213634150b4505cd6fcab9910;p=gcc.git Refactor IPA devirt a bit. 2019-12-02 Martin Liska * ipa-devirt.c (warn_types_mismatch): Use get_odr_name_for_type function. (debug_tree_odr_name): New. * ipa-utils.h (get_odr_name_for_type): New. 2019-12-02 Martin Liska * g++.dg/lto/odr-7_0.C: New test. * g++.dg/lto/odr-7_1.C: New test. From-SVN: r278898 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d342f4cf10..765e01565d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-12-02 Martin Liska + + * ipa-devirt.c (warn_types_mismatch): Use get_odr_name_for_type + function. + (debug_tree_odr_name): New. + * ipa-utils.h (get_odr_name_for_type): New. + 2019-12-02 Richard Biener PR tree-optimization/92742 diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index a884a465a5d..1017b2a5c7c 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1036,20 +1036,13 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2) /* If types have mangled ODR names and they are different, it is most informative to output those. This also covers types defined in different namespaces. */ - if (TYPE_NAME (mt1) && TYPE_NAME (mt2) - && TREE_CODE (TYPE_NAME (mt1)) == TYPE_DECL - && TREE_CODE (TYPE_NAME (mt2)) == TYPE_DECL - && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (mt1)) - && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (mt2)) - && DECL_ASSEMBLER_NAME (TYPE_NAME (mt1)) - != DECL_ASSEMBLER_NAME (TYPE_NAME (mt2))) - { - char *name1 = xstrdup (cplus_demangle - (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (mt1))), - DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES)); - char *name2 = cplus_demangle - (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (mt2))), - DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES); + const char *odr1 = get_odr_name_for_type (mt1); + const char *odr2 = get_odr_name_for_type (mt2); + if (odr1 != NULL && odr2 != NULL && odr1 != odr2) + { + const int opts = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; + char *name1 = xstrdup (cplus_demangle (odr1, opts)); + char *name2 = xstrdup (cplus_demangle (odr2, opts)); if (name1 && name2 && strcmp (name1, name2)) { inform (loc_t1, @@ -3989,4 +3982,20 @@ make_pass_ipa_devirt (gcc::context *ctxt) return new pass_ipa_devirt (ctxt); } +/* Print ODR name of a TYPE if available. + Use demangler when option DEMANGLE is used. */ + +DEBUG_FUNCTION void +debug_tree_odr_name (tree type, bool demangle) +{ + const char *odr = get_odr_name_for_type (type); + if (demangle) + { + const int opts = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; + odr = cplus_demangle (odr, opts); + } + + fprintf (stderr, "%s\n", odr); +} + #include "gt-ipa-devirt.h" diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h index 60c52e0fa53..81a54797558 100644 --- a/gcc/ipa-utils.h +++ b/gcc/ipa-utils.h @@ -248,4 +248,18 @@ odr_type_p (const_tree t) && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)); } +/* If TYPE has mangled ODR name, return it. Otherwise return NULL. + The function works only when free_lang_data is run. */ + +inline const char * +get_odr_name_for_type (tree type) +{ + tree type_name = TYPE_NAME (type); + if (type_name == NULL_TREE + || !DECL_ASSEMBLER_NAME_SET_P (type_name)) + return NULL; + + return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (type_name)); +} + #endif /* GCC_IPA_UTILS_H */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8d118a35a59..bc991e229e9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-12-02 Martin Liska + + * g++.dg/lto/odr-7_0.C: New test. + * g++.dg/lto/odr-7_1.C: New test. + 2019-11-30 Jan Hubicka * g++.dg/lto/inline-crossmodule-1_0.C: fix template. diff --git a/gcc/testsuite/g++.dg/lto/odr-7_0.C b/gcc/testsuite/g++.dg/lto/odr-7_0.C new file mode 100644 index 00000000000..e33b8192bc1 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/odr-7_0.C @@ -0,0 +1,18 @@ +// { dg-lto-do link } + +struct bar // { dg-lto-message "type name 'bar' should match type name 'foobar'" } +{ + int xxx; +}; + +struct foo // { dg-lto-warning "8: 'struct foo' violates the C\\+\\+ One Definition Rule" } +{ + bar a; +}; + +foo myfoo2; + +int +main() +{ +} diff --git a/gcc/testsuite/g++.dg/lto/odr-7_1.C b/gcc/testsuite/g++.dg/lto/odr-7_1.C new file mode 100644 index 00000000000..464bd895900 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/odr-7_1.C @@ -0,0 +1,13 @@ +template +struct foobar +{ + int xxx; + T pes; +}; + +struct foo +{ + foobar a; +}; + +foo myfoo;