https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70594
--- Comment #47 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Ok, found one bug in the unused block pruning: --- gcc/ipa-polymorphic-call.c.jj 2016-03-30 16:00:17.000000000 +0200 +++ gcc/ipa-polymorphic-call.c 2016-04-14 16:45:45.407754387 +0200 @@ -479,16 +479,12 @@ contains_type_p (tree outer_type, HOST_W } -/* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor. +/* Return a FUNCTION_DECL if FN represent a constructor or destructor. If CHECK_CLONES is true, also check for clones of ctor/dtors. */ tree -inlined_polymorphic_ctor_dtor_block_p (tree block, bool check_clones) +polymorphic_ctor_dtor_p (tree fn, bool check_clones) { - tree fn = block_ultimate_origin (block); - if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL) - return NULL_TREE; - if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn))) { @@ -510,6 +506,19 @@ inlined_polymorphic_ctor_dtor_block_p (t return fn; } +/* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor. + If CHECK_CLONES is true, also check for clones of ctor/dtors. */ + +tree +inlined_polymorphic_ctor_dtor_block_p (tree block, bool check_clones) +{ + tree fn = block_ultimate_origin (block); + if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL) + return NULL_TREE; + + return polymorphic_ctor_dtor_p (fn, check_clones); +} + /* We know that the instance is stored in variable or parameter (not dynamically allocated) and we want to disprove the fact --- gcc/ipa-utils.h.jj 2016-01-04 14:55:51.000000000 +0100 +++ gcc/ipa-utils.h 2016-04-14 16:46:08.828444152 +0200 @@ -70,6 +70,7 @@ void dump_possible_polymorphic_call_targ bool possible_polymorphic_call_target_p (tree, HOST_WIDE_INT, const ipa_polymorphic_call_context &, struct cgraph_node *); +tree polymorphic_ctor_dtor_p (tree, bool); tree inlined_polymorphic_ctor_dtor_block_p (tree, bool); bool decl_maybe_in_construction_p (tree, tree, gimple *, tree); tree vtable_pointer_value_to_binfo (const_tree); --- gcc/tree-ssa-live.c.jj 2016-01-04 14:55:51.000000000 +0100 +++ gcc/tree-ssa-live.c 2016-04-14 16:47:33.343324654 +0200 @@ -855,7 +855,9 @@ remove_unused_locals (void) cfun->local_decls->truncate (dstidx); } - remove_unused_scope_block_p (DECL_INITIAL (current_function_decl), false); + remove_unused_scope_block_p (DECL_INITIAL (current_function_decl), + polymorphic_ctor_dtor_p (current_function_decl, + true) != NULL_TREE); clear_unused_block_pointer (); BITMAP_FREE (usedvars); but sadly this still doesn't fix it (though, fixes at least the first case where we nuke the needed BLOCK).