mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 02:44:18 +08:00
Fixed extract_types_for_resx function
The function was recursive in nature and there is a chance of runnign out of stack, so now ann iterative approach was used to get the types for resx
This commit is contained in:
parent
c4ab1c5710
commit
c756ee328c
101
gcc/tree-eh.cc
101
gcc/tree-eh.cc
@ -3183,60 +3183,59 @@ stmt_throw_types (function *, gimple *stmt, vec<tree> *ret_vector)
|
||||
}
|
||||
}
|
||||
|
||||
// To get the all exception types from a resx stmt
|
||||
static bool
|
||||
extract_types_for_resx (basic_block bb, vec<tree> *ret_vector)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
// Iterate over edges to walk up the basic blocks
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
// Get the last stmt of the basic block as it is an EH stmt
|
||||
bb = e->src;
|
||||
gimple_stmt_iterator gsi = gsi_last_bb (bb);
|
||||
gimple *last_stmt = gsi_stmt (gsi);
|
||||
|
||||
if (bb->aux)
|
||||
continue;
|
||||
bb->aux = (void *)1;
|
||||
|
||||
if (last_stmt && (e->flags & EDGE_EH))
|
||||
{
|
||||
if (gimple_code (last_stmt) == GIMPLE_CALL)
|
||||
{
|
||||
// check if its a throw
|
||||
if (!extract_types_for_call (as_a<gcall *> (last_stmt),
|
||||
ret_vector))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
else if (gimple_code (last_stmt) == GIMPLE_RESX)
|
||||
{
|
||||
// Recursively processing resx
|
||||
// FIXME: to get this linear, we should cache results.
|
||||
if (!extract_types_for_resx (last_stmt, ret_vector))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* FIXME: remove recursion here, so we do not run out of stack. */
|
||||
else if (!extract_types_for_resx (e->src, ret_vector))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// To get the all exception types from a resx stmt
|
||||
// To get the all exception types from a resx stmt (iterative version)
|
||||
bool
|
||||
extract_types_for_resx (gimple *resx_stmt, vec<tree> *ret_vector)
|
||||
{
|
||||
basic_block bb = gimple_bb (resx_stmt);
|
||||
bool ret = extract_types_for_resx (bb, ret_vector);
|
||||
/* FIXME: this is non-linear. */
|
||||
clear_aux_for_blocks ();
|
||||
return ret;
|
||||
basic_block start_bb = gimple_bb (resx_stmt);
|
||||
hash_set<basic_block> visited_blocks;
|
||||
vec<basic_block> block_stack;
|
||||
|
||||
block_stack.safe_push(start_bb);
|
||||
|
||||
while (!block_stack.is_empty())
|
||||
{
|
||||
basic_block bb = block_stack.pop();
|
||||
if (visited_blocks.contains(bb))
|
||||
continue;
|
||||
|
||||
visited_blocks.add(bb);
|
||||
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
gimple_stmt_iterator gsi = gsi_last_bb(bb);
|
||||
gimple *last_stmt = gsi_stmt(gsi);
|
||||
|
||||
|
||||
FOR_EACH_EDGE(e, ei, bb->preds)
|
||||
{
|
||||
basic_block pred_bb = e->src;
|
||||
|
||||
if (e->flags & EDGE_EH)
|
||||
{
|
||||
gimple_stmt_iterator pred_gsi = gsi_last_bb(pred_bb);
|
||||
gimple *pred_last_stmt = gsi_stmt(pred_gsi);
|
||||
|
||||
if (gimple_code(pred_last_stmt) == GIMPLE_CALL)
|
||||
{
|
||||
if (!extract_types_for_call(as_a<gcall*>(pred_last_stmt), ret_vector))
|
||||
return false;
|
||||
}
|
||||
else if (gimple_code(pred_last_stmt) == GIMPLE_RESX)
|
||||
{
|
||||
// Add the predecessor block to the stack for further exploration
|
||||
block_stack.safe_push(pred_bb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
block_stack.safe_push(pred_bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear_aux_for_blocks();
|
||||
return true;
|
||||
}
|
||||
|
||||
// To get the types being thrown outside of a function
|
||||
|
Loading…
Reference in New Issue
Block a user