On 12/2/19 11:50 AM, Jan Hubicka wrote:
Hello.
The patches makes a small refactoring in ipa-devirt.c and comes up
with a handy debugging function debug_tree_odr_name.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed?
Thanks,
Martin
gcc/ChangeLog:
2019-12-02 Martin Liska <mli...@suse.cz>
* ipa-devirt.c (warn_types_mismatch): Use get_odr_name_for_type.
* print-tree.c (debug_tree_odr_name): New.
* print-tree.h (debug_tree_odr_name): New.
* tree.h (get_odr_name_for_type): New.
gcc/testsuite/ChangeLog:
2019-12-02 Martin Liska <mli...@suse.cz>
* g++.dg/lto/odr-7_0.C: New test.
* g++.dg/lto/odr-7_1.C: New test.
This is OK except ...
+/* 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)
I would probably keep these in ipa-devirt since it has everything
related to devirtualization in it and there is not much related
to normal tree printing machinery.
+/* If TYPE has mangled ODR name, return it. Otherwise return NULL. */
+
+inline const char *
+get_odr_name_for_type (tree type)
Similarly here I would keep it in ipa-util where all the other ODR
related stuff is (next stage1 we could move it into something like
odr-type.[ch]).
Also document that it works only after free_lang_data was run.
Sure, I'm sending updated version of the patch.
Ready for trunk now?
Martin
Honza
+{
+ 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));
+}
+
/* A struct for encapsulating location information about an operator
and the operation built from it.
>From 6126f8f44106cd779a2d77a4755c68bcf6b9fa20 Mon Sep 17 00:00:00 2001
From: Martin Liska <mli...@suse.cz>
Date: Mon, 2 Dec 2019 09:59:26 +0100
Subject: [PATCH] Refactor IPA devirt a bit.
gcc/ChangeLog:
2019-12-02 Martin Liska <mli...@suse.cz>
* 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.
gcc/testsuite/ChangeLog:
2019-12-02 Martin Liska <mli...@suse.cz>
* g++.dg/lto/odr-7_0.C: New test.
* g++.dg/lto/odr-7_1.C: New test.
---
gcc/ipa-devirt.c | 37 +++++++++++++++++++-----------
gcc/ipa-utils.h | 14 +++++++++++
gcc/testsuite/g++.dg/lto/odr-7_0.C | 18 +++++++++++++++
gcc/testsuite/g++.dg/lto/odr-7_1.C | 13 +++++++++++
4 files changed, 68 insertions(+), 14 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/lto/odr-7_0.C
create mode 100644 gcc/testsuite/g++.dg/lto/odr-7_1.C
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/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<float>'" }
+{
+ 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 <class T>
+struct foobar
+{
+ int xxx;
+ T pes;
+};
+
+struct foo
+{
+ foobar<float> a;
+};
+
+foo myfoo;
--
2.24.0