http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54314
--- Comment #26 from Jan Hubicka <hubicka at ucw dot cz> 2013-01-28 14:56:12 UTC --- > perhaps making them hidden whenever possible is really desirable. Yes, this seems fine to me. Just to be sure I understand the problem fully. I believe there is still problem with folding. When folding references through external vtable I think we can still invent direct references to construction vtable. While doing so we go through logic in can_refer_decl_in_current_unit_p. This is trying to validate the reference to the symbol referred only outside of current unit. I sort of hacked it together trying to work out what rules are. This is all wrong for construction vtables where, if I understand it right, we can not reffer them in any case because other file may be from other compiler. (with excetion of ltrans and LTO, also resolution data may tell us that the symbol is defined?) /* We are folding reference from external vtable. The vtable may reffer to a symbol keyed to other compilation unit. The other compilation unit may be in separate DSO and the symbol may be hidden. */ if (DECL_VISIBILITY_SPECIFIED (decl) && DECL_EXTERNAL (decl) && (!(snode = symtab_get_node (decl)) || !snode->symbol.in_other_partition)) return false; /* When function is public, we always can introduce new reference. Exception are the COMDAT functions where introducing a direct reference imply need to include function body in the curren tunit. */ if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) return true; /* We are not at ltrans stage; so don't worry about WHOPR. Also when still gimplifying all referred comdat functions will be produced. As observed in PR20991 for already optimized out comdat virtual functions it may be tempting to not necessarily give up because the copy will be output elsewhere when corresponding vtable is output. This is however not possible - ABI specify that COMDATs are output in units where they are used and when the other unit was compiled with LTO it is possible that vtable was kept public while the function itself was privatized. */ if (!flag_ltrans && (!DECL_COMDAT (decl) || !cgraph_function_flags_ready)) return true; /* OK we are seeing either COMDAT or static variable. In this case we must check that the definition is still around so we can refer it. */ if (TREE_CODE (decl) == FUNCTION_DECL) .... return true; I guess we need to add check for construction vtables and disable references There are options. 1) Just add the check. We will then miss all devirtualization oppurtunities through the construction vtable. I guess it is what we should do for 4.8 and earlier. Marking them hidden will prevent folders from using them, but what happens on targets not supporting visibility? 2) We may teach all optimizers, like ccp/gvn and fold to only "jump across them" and fold only when the reference to construction vtable is used by reference to method itself, but it is not how the optimizers are organized - they always do one folding at a time and expect that they can reffer to them. 3) Perhaps we can use DECL_VALUE_EXPR or somethin similar to keep track of the canonical way to reffer into tthe construction vtable? (i.e. by reference to vtable) We can then lower all direct references to the indirect references late, i.e. in expansion? I suppose 3) makes most sense in longer run. Implementing 2) without missing optimization oppurtunities would be hard. Honza