https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120098
--- Comment #9 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
Actually I got confused. Call of wrap is fine since it expects MultiTermDocs
instead of C and C in destruction is fine here.
With anonymous namespace version what gets wrong is
type_possibly_instantiated_p. It looks for vtable of MultiTermDocs being used.
It is not, but the destruction vtable is.
We have
MEM[(struct MultiTermDocs *)this_5(D)]._vptr.MultiTermDocs = &MEM <int
(*__vtbl_ptr_type) ()> [(void *)&_ZTC1C0_13MultiTermDocs + 24B];
which makes MultiTermDocs::fn1 reachable, but that is not constructor of
MultiTermDocs itself rather a construction vtable for MultiTermDocs-in-C
diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index c10d67f1e67..ba5a49b4d27 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -284,7 +284,7 @@ type_possibly_instantiated_p (tree t)
if (TREE_CODE (vtable) == POINTER_PLUS_EXPR)
vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0);
vnode = varpool_node::get (vtable);
- return vnode && vnode->definition;
+ return (vnode && vnode->definition) || 1;
}
/* Return true if T or type derived from T may have instance. */
is a workaround. I need to figure out how to record those - that looks like a
trouble :(.
With -flto the problem is triggered by same scenario but goes differently:
1) We do not stream the vtable since it is unused
2) ipa-cp finds the call target by normal folding of aggregate constructors
and then asks polymorphic call analysis if the target is possible
3) possible_polymorphic_call_targets looks up the vtable and fail and return
partial list
4) possible_polymorphic_call_target_p then sees incomplete list but believes
that all symbols with definition should be on it which is not true due to the
missed vtable.
diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index c10d67f1e67..25de7ff636d 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -3502,7 +3502,7 @@ possible_polymorphic_call_target_p (tree otr_type,
/* At a moment we allow middle end to dig out new external declarations
as a targets of polymorphic calls. */
- if (!final && !n->definition)
+ if (!final /*&& !n->definition*/)
return true;
return false;
}