diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-10 21:34:37 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-10 21:34:37 +0000 |
commit | 2441731ca04ea6244ad247893847430f08c4979d (patch) | |
tree | a257114435a40ca9a3037d56f5138b40d8c8afa7 /gcc/ipa-devirt.c | |
parent | 0dfd08b17e2d1b0aca02d5828a559fe152fccb78 (diff) | |
download | gcc-2441731ca04ea6244ad247893847430f08c4979d.tar.gz |
PR ipa/58585
* ipa-devirt.c (build_type_inheritance_graph): Also add types of vtables
into the type inheritance graph.
* g++.dg/torture/pr58585.C: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206543 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-devirt.c')
-rw-r--r-- | gcc/ipa-devirt.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index b0bedacd609..fb03dd2618d 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -542,7 +542,7 @@ method_class_type (tree t) void build_type_inheritance_graph (void) { - struct cgraph_node *n; + struct symtab_node *n; FILE *inheritance_dump_file; int flags; @@ -554,10 +554,37 @@ build_type_inheritance_graph (void) /* We reconstruct the graph starting of types of all methods seen in the the unit. */ - FOR_EACH_FUNCTION (n) - if (DECL_VIRTUAL_P (n->decl) + FOR_EACH_SYMBOL (n) + if (is_a <cgraph_node> (n) + && DECL_VIRTUAL_P (n->decl) && symtab_real_symbol_p (n)) get_odr_type (method_class_type (TREE_TYPE (n->decl)), true); + + /* Look also for virtual tables of types that do not define any methods. + + We need it in a case where class B has virtual base of class A + re-defining its virtual method and there is class C with no virtual + methods with B as virtual base. + + Here we output B's virtual method in two variant - for non-virtual + and virtual inheritance. B's virtual table has non-virtual version, + while C's has virtual. + + For this reason we need to know about C in order to include both + variants of B. More correctly, record_target_from_binfo should + add both variants of the method when walking B, but we have no + link in between them. + + We rely on fact that either the method is exported and thus we + assume it is called externally or C is in anonymous namespace and + thus we will see the vtable. */ + + else if (is_a <varpool_node> (n) + && DECL_VIRTUAL_P (n->decl) + && TREE_CODE (DECL_CONTEXT (n->decl)) == RECORD_TYPE + && TYPE_BINFO (DECL_CONTEXT (n->decl)) + && polymorphic_type_binfo_p (TYPE_BINFO (DECL_CONTEXT (n->decl)))) + get_odr_type (DECL_CONTEXT (n->decl), true); if (inheritance_dump_file) { dump_type_inheritance_graph (inheritance_dump_file); |