Refactor IPA devirt a bit.
authorMartin Liska <mliska@suse.cz>
Mon, 2 Dec 2019 11:18:31 +0000 (12:18 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Mon, 2 Dec 2019 11:18:31 +0000 (11:18 +0000)
2019-12-02  Martin Liska  <mliska@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.
2019-12-02  Martin Liska  <mliska@suse.cz>

* g++.dg/lto/odr-7_0.C: New test.
* g++.dg/lto/odr-7_1.C: New test.

From-SVN: r278898

gcc/ChangeLog
gcc/ipa-devirt.c
gcc/ipa-utils.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lto/odr-7_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/odr-7_1.C [new file with mode: 0644]

index 1d342f4..765e015 100644 (file)
@@ -1,3 +1,10 @@
+2019-12-02  Martin Liska  <mliska@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.
+
 2019-12-02  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/92742
index a884a46..1017b2a 100644 (file)
@@ -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"
index 60c52e0..81a5479 100644 (file)
@@ -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  */
index 8d118a3..bc991e2 100644 (file)
@@ -1,3 +1,8 @@
+2019-12-02  Martin Liska  <mliska@suse.cz>
+
+       * g++.dg/lto/odr-7_0.C: New test.
+       * g++.dg/lto/odr-7_1.C: New test.
+
 2019-11-30  Jan Hubicka  <hubicka@ucw.cz>
 
        * 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 (file)
index 0000000..e33b819
--- /dev/null
@@ -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 (file)
index 0000000..464bd89
--- /dev/null
@@ -0,0 +1,13 @@
+template <class T>
+struct foobar
+{
+  int xxx;
+  T pes;
+};
+
+struct foo
+{
+  foobar<float> a;
+};
+
+foo myfoo;