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

Jan Hubicka <hubicka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2016-01-10
           Assignee|unassigned at gcc dot gnu.org      |hubicka at gcc dot 
gnu.org
     Ever confirmed|0                           |1

--- Comment #3 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
This is the result of analysis:
Procesing function void test(Interface&)/12
Introduced new external node (void __cxa_pure_virtual()/26).
  Targets of polymorphic call of type 0:struct Interface token 3
    Outer type (dynamic):struct Interface (or a derived type) offset 0
    This is partial list; extra targets may be defined in other units. (derived
types included)
       virtual void Concrete::virtualFunc2()/11

code.C:16:19: note: speculatively devirtualizing call in void
test(Interface&)/12 to virtual void Concrete::virtualFunc2()/11
Indirect call -> speculative call void test(Interface&)/12 => virtual void
Concrete::virtualFunc2()/11
  Targets of polymorphic call of type 0:struct Interface token 2
    Outer type (dynamic):struct Interface (or a derived type) offset 0
    This is partial list; extra targets may be defined in other units. (derived
types included)
       virtual void Concrete::virtualFunc()/10 (no definition inline)
  Speculative targets:

the problem is that list of Speculative targets is empty which makes us to
ignore the fact that even non-speculatively there is only one possible target.

The reason is that the second function does not pass
can_refer_decl_in_current_unit_p:

149       snode = symtab_node::get (decl);
150       if (!snode
151           || ((!snode->definition || DECL_EXTERNAL (decl))
152               && (!snode->in_other_partition
153                   || (!snode->forced_by_abi && !snode->force_output))))
154         return false;

and node is:

(gdb) p snode->debug ()
_ZN8Concrete11virtualFuncEv/10 (virtual void Concrete::virtualFunc())
@0x7ffff6c4f170
  Type: function
  Body removed by symtab_remove_unreachable_nodes
  Visibility: externally_visible public weak comdat
comdat_group:_ZN8Concrete11virtualFuncEv one_only virtual
  References: 
  Referring: 
  Availability: not_available
  First run: 0
  Function flags: icf_merged
  Called by: 
  Calls: 

which is done by ipa-icf::merge:

Wrapper cannot be created because of COMDAT                                     
Unified; Function body was removed.

This is because ipa-icf thinks that since there are no calls or direct uses, it
may get rid of the function.

I am testing the following:

Index: ../../gcc/ipa-icf.c
===================================================================
--- ../../gcc/ipa-icf.c (revision 232179)
+++ ../../gcc/ipa-icf.c (working copy)
@@ -1305,6 +1305,7 @@ sem_function::merge (sem_item *alias_ite

       /* If all callers was redirected, do not produce wrapper.  */
       if (alias->can_remove_if_no_direct_calls_p ()
+         && !DECL_VIRTUAL_P (alias->decl)
          && !alias->has_aliases_p ())
        {
          create_wrapper = false;

Reply via email to