https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93115

--- Comment #4 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
The problem here is that we produce ipa-cp clone to devirtualize v::av which
also lead to devirtualization of m::av, but we miss this optimization. After
inlining we remove m::av and while producing the ipa-cp clone we devirtualize
to it which elads to undefined reference.

I am testing the following:
Index: ipa.c
===================================================================
--- ipa.c       (revision 279810)
+++ ipa.c       (working copy)
@@ -187,6 +187,7 @@ walk_polymorphic_call_targets (hash_set<
       for (i = 0; i < targets.length (); i++)
        {
          struct cgraph_node *n = targets[i];
+         bool added = false;

          /* Do not bother to mark virtual methods in anonymous namespace;
             either we will find use of virtual table defining it, or it is
@@ -212,11 +213,18 @@ walk_polymorphic_call_targets (hash_set<
                    && symtab->state < IPA_SSA_AFTER_INLINING)
                  reachable->add (body);
               reachable->add (n);
+              added = true;
             }
          /* Even after inlining we want to keep the possible targets in the
             boundary, so late passes can still produce direct call even if
-            the chance for inlining is lost.  */
-         enqueue_node (n, first, reachable);
+            the chance for inlining is lost.
+            Do not keep references to comdat groups - removing their
definition
+            first and adding references later is going to give undefined
+            reference errors.  */
+         if (added || (!DECL_COMDAT (n->decl)
+                       || DECL_EXTERNAL (n->decl)
+                       || !TREE_PUBLIC (n->decl)))
+           enqueue_node (n, first, reachable);
        }
     }

Reply via email to