http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58585
--- Comment #20 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
Looking even deeper, there are two problems. The first is that we miss C in
type hiearchy graph.
C however may be defined in other unit. We do mistake already while walking B.
There are two variants of B::foo. One when base A is non-virtual and other
when it is virtual.
B's vtable is:
_ZTV1C:
.quad 0
.quad 8
.quad 8
.quad 0
.quad _ZTI1C
.quad _ZTv0_n24_N1B3fooEv
.quad -8
.quad 0
.quad -8
.quad _ZTI1C
.quad _ZN1B3fooEv
Our walking logic misses the fact that descendands of B may use the thunk
instead of FOO based on presence of virtual inheritance.
I suppose for complete correctness I would have to add code associating methods
with their virtual thunks and lookup the thunks when walking B and knowng that
I am interested in the derived types.
Simpler solution solving both problems practically is probably to simply walk
known vtables and insert their types to the type hiearchy: all internal
devirtualizations will be correct and all the missed calls to thunk from vtable
of type defined externally are harmless: the visibility code already makes all
the assumption that the call can happen.