re PR tree-optimization/42890 (Crash in type_like_member_ptr_p in ipa-prop.c:382)

PR tree-optimization/42890
	* tree-inline.c (delete_unreachable_blocks_update_callgraph): New
	function backported from the trunk.
	(tree_function_versioning): Call it instead of
	delete_unreachable_blocks.

	* g++.dg/torture/pr42890.C: New test.

From-SVN: r156605
This commit is contained in:
Jakub Jelinek 2010-02-08 16:50:59 +01:00 committed by Jakub Jelinek
parent 64604c32af
commit fe872b6f64
4 changed files with 77 additions and 1 deletions

View File

@ -1,5 +1,11 @@
2010-02-08 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/42890
* tree-inline.c (delete_unreachable_blocks_update_callgraph): New
function backported from the trunk.
(tree_function_versioning): Call it instead of
delete_unreachable_blocks.
PR tree-optimization/42931
* tree-loop-linear.c (try_interchange_loops): Don't call
double_int_mul if estimated_loop_iterations failed.

View File

@ -1,3 +1,8 @@
2010-02-08 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/42890
* g++.dg/torture/pr42890.C: New test.
2010-02-08 H.J. Lu <hongjiu.lu@intel.com>
* gcc.dg/ipa/pr42706.c: Removed.

View File

@ -0,0 +1,25 @@
// PR tree-optimization/42890
// { dg-do compile }
extern "C" int puts (const char *) throw ();
struct S
{
const char *a;
const char **b;
S (const char *s) { a = s; b = &a; }
~S () { puts (a); }
};
void
foo (int (*fn) (const char *))
{
S a ("foo");
fn ("bar");
}
int
main ()
{
foo (puts);
}

View File

@ -4271,6 +4271,46 @@ tree_versionable_function_p (tree fndecl)
return true;
}
/* Delete all unreachable basic blocks and update callgraph.
Doing so is somewhat nontrivial because we need to update all clones and
remove inline function that become unreachable. */
static bool
delete_unreachable_blocks_update_callgraph (copy_body_data *id)
{
bool changed = false;
basic_block b, next_bb;
find_unreachable_blocks ();
/* Delete all unreachable basic blocks. */
for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR; b = next_bb)
{
next_bb = b->next_bb;
if (!(b->flags & BB_REACHABLE))
{
gimple_stmt_iterator bsi;
for (bsi = gsi_start_bb (b); !gsi_end_p (bsi); gsi_next (&bsi))
if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL)
{
struct cgraph_edge *e;
if ((e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL)
cgraph_remove_edge (e);
}
delete_basic_block (b);
changed = true;
}
}
if (changed)
tidy_fallthru_edges ();
return changed;
}
/* Create a copy of a function's tree.
OLD_DECL and NEW_DECL are FUNCTION_DECL tree nodes
of the original function and the new copied function
@ -4445,7 +4485,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
if (!update_clones)
delete_unreachable_blocks ();
delete_unreachable_blocks_update_callgraph (&id);
update_ssa (TODO_update_ssa);
if (!update_clones)
{