mirror of git://gcc.gnu.org/git/gcc.git
Formatting for all functions done according to GNU standards and fixed testsuite fail bugs
This commit is contained in:
parent
f5b29909d5
commit
c4ab1c5710
476
gcc/tree-eh.cc
476
gcc/tree-eh.cc
|
|
@ -2283,14 +2283,14 @@ same_or_derived_type (tree t1, tree t2)
|
||||||
t2 = TYPE_MAIN_VARIANT (t2);
|
t2 = TYPE_MAIN_VARIANT (t2);
|
||||||
if (t1 == t2)
|
if (t1 == t2)
|
||||||
return true;
|
return true;
|
||||||
while ( (TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE)
|
while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE)
|
||||||
&& TREE_CODE (t1) == TREE_CODE (t2))
|
&& TREE_CODE (t1) == TREE_CODE (t2))
|
||||||
{
|
{
|
||||||
t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1));
|
t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1));
|
||||||
t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2));
|
t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2));
|
||||||
if (TREE_CODE (t1) == VOID_TYPE)
|
if (TREE_CODE (t1) == VOID_TYPE)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (t1 == t2)
|
if (t1 == t2)
|
||||||
return true;
|
return true;
|
||||||
if (TREE_CODE (t2) == NULLPTR_TYPE && TREE_CODE (t1) == POINTER_TYPE)
|
if (TREE_CODE (t2) == NULLPTR_TYPE && TREE_CODE (t1) == POINTER_TYPE)
|
||||||
|
|
@ -2300,153 +2300,186 @@ same_or_derived_type (tree t1, tree t2)
|
||||||
return odr_equivalent_or_derived_p (t1, t2);
|
return odr_equivalent_or_derived_p (t1, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a landing pad can handle any of the given exception types
|
// Check if a region can handle any of the given exception types
|
||||||
static bool match_lp (eh_region region, vec<tree> *exception_types){
|
static bool
|
||||||
// Ensure the region is of type ERT_TRY
|
match_lp (eh_region region, vec<tree> *exception_types)
|
||||||
if (region && region->type == ERT_TRY) {
|
{
|
||||||
eh_catch_d *catch_handler = region->u.eh_try.first_catch;
|
// Ensure the region is of type ERT_TRY
|
||||||
|
if (region && region->type == ERT_TRY)
|
||||||
|
{
|
||||||
|
eh_catch_d *catch_handler = region->u.eh_try.first_catch;
|
||||||
|
|
||||||
while (catch_handler) {
|
while (catch_handler)
|
||||||
tree type_list = catch_handler->type_list;
|
{
|
||||||
|
tree type_list = catch_handler->type_list;
|
||||||
|
|
||||||
if (type_list == NULL) {
|
if (type_list == NULL)
|
||||||
return true;
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (tree t = type_list; t; t = TREE_CHAIN (t)) {
|
for (tree t = type_list; t; t = TREE_CHAIN (t))
|
||||||
tree type = TREE_VALUE (t);
|
{
|
||||||
for (unsigned i = 0; i < exception_types->length (); ++i) {
|
tree type = TREE_VALUE (t);
|
||||||
|
for (unsigned i = 0; i < exception_types->length (); ++i)
|
||||||
|
{
|
||||||
// match found or a catch-all handler (NULL)
|
// match found or a catch-all handler (NULL)
|
||||||
if (!type || same_or_derived_type (type, (*exception_types)[i])) {
|
if (!type
|
||||||
return true;
|
|| same_or_derived_type (type, (*exception_types)[i]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch_handler = catch_handler->next_catch;
|
catch_handler = catch_handler->next_catch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unlink_eh_region(eh_region region) {
|
static void
|
||||||
eh_region *link;
|
unlink_eh_region (eh_region region)
|
||||||
|
{
|
||||||
|
eh_region *link;
|
||||||
|
|
||||||
// Check if region is root
|
// Check if region is root
|
||||||
if (!region->outer) {
|
if (!region->outer)
|
||||||
gcc_unreachable();
|
{
|
||||||
return;
|
gcc_unreachable ();
|
||||||
}
|
|
||||||
|
|
||||||
link = ®ion->outer->inner;
|
|
||||||
|
|
||||||
while (*link && *link != region) {
|
|
||||||
link = &(*link)->next_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the region is in the peer chain
|
|
||||||
gcc_assert(*link == region);
|
|
||||||
|
|
||||||
*link = region->next_peer;
|
|
||||||
|
|
||||||
region->outer = NULL;
|
|
||||||
region->next_peer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reinsert_eh_region (eh_region region, eh_region new_outer) {
|
|
||||||
region->outer = new_outer;
|
|
||||||
|
|
||||||
// Insert region as the inner of new_outer, or at the top of the tree
|
|
||||||
if (new_outer) {
|
|
||||||
region->next_peer = new_outer->inner;
|
|
||||||
new_outer->inner = region;
|
|
||||||
} else {
|
|
||||||
region->next_peer = cfun->eh->region_tree;
|
|
||||||
cfun->eh->region_tree = region;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to update landing pad and region in throw_stmt_table for a given statement
|
|
||||||
void update_stmt_eh_region (gimple *stmt) {
|
|
||||||
auto_vec<tree> exception_types;
|
|
||||||
if (!stmt_throw_types (cfun, stmt, &exception_types)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lp_nr = lookup_stmt_eh_lp_fn (cfun, stmt);
|
|
||||||
if (lp_nr <= 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
|
link = ®ion->outer->inner;
|
||||||
if (!lp) {
|
|
||||||
return;
|
while (*link && *link != region)
|
||||||
|
{
|
||||||
|
link = &(*link)->next_peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
eh_region region = lp->region;
|
// Ensure the region is in the peer chain
|
||||||
eh_region resx_region = NULL;
|
gcc_assert (*link == region);
|
||||||
|
|
||||||
bool update = false;
|
*link = region->next_peer;
|
||||||
if (gimple_code (stmt) == GIMPLE_RESX)
|
|
||||||
resx_region = get_eh_region_from_number (gimple_resx_region (as_a <gresx *> (stmt)));
|
|
||||||
|
|
||||||
// Walk up the region tree
|
region->outer = NULL;
|
||||||
while (region) {
|
region->next_peer = NULL;
|
||||||
switch (region->type) {
|
}
|
||||||
case ERT_CLEANUP:
|
|
||||||
if (!update)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (gimple_code (stmt) == GIMPLE_RESX){
|
static void
|
||||||
|
reinsert_eh_region (eh_region region, eh_region new_outer)
|
||||||
|
{
|
||||||
|
region->outer = new_outer;
|
||||||
|
|
||||||
|
// Insert region as the inner of new_outer, or at the top of the tree
|
||||||
|
if (new_outer)
|
||||||
|
{
|
||||||
|
region->next_peer = new_outer->inner;
|
||||||
|
new_outer->inner = region;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
region->next_peer = cfun->eh->region_tree;
|
||||||
|
cfun->eh->region_tree = region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to update landing pad and region in throw_stmt_table for a given
|
||||||
|
statement */
|
||||||
|
void
|
||||||
|
update_stmt_eh_region (gimple *stmt)
|
||||||
|
{
|
||||||
|
auto_vec<tree> exception_types;
|
||||||
|
if (!stmt_throw_types (cfun, stmt, &exception_types))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eh_region region;
|
||||||
|
|
||||||
|
int lp_nr = lookup_stmt_eh_lp_fn (cfun, stmt);
|
||||||
|
if (lp_nr <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
|
||||||
|
if (!lp)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
region = lp->region;
|
||||||
|
eh_region resx_region = NULL;
|
||||||
|
|
||||||
|
bool update = false;
|
||||||
|
if (gimple_code (stmt) == GIMPLE_RESX)
|
||||||
|
resx_region = get_eh_region_from_number (
|
||||||
|
gimple_resx_region (as_a<gresx *> (stmt)));
|
||||||
|
|
||||||
|
// Walk up the region tree
|
||||||
|
while (region)
|
||||||
|
{
|
||||||
|
switch (region->type)
|
||||||
|
{
|
||||||
|
case ERT_CLEANUP:
|
||||||
|
if (!update)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (gimple_code (stmt) == GIMPLE_RESX)
|
||||||
|
{
|
||||||
|
unlink_eh_region (resx_region);
|
||||||
|
reinsert_eh_region (resx_region, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_stmt_from_eh_lp_fn (cfun, stmt);
|
||||||
|
record_stmt_eh_region (region, stmt);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ERT_TRY:
|
||||||
|
if (match_lp (region, &exception_types))
|
||||||
|
{
|
||||||
|
if (!update)
|
||||||
|
return;
|
||||||
|
if (gimple_code (stmt) == GIMPLE_RESX)
|
||||||
|
{
|
||||||
unlink_eh_region (resx_region);
|
unlink_eh_region (resx_region);
|
||||||
reinsert_eh_region (resx_region, region);
|
reinsert_eh_region (resx_region, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_stmt_from_eh_lp_fn (cfun, stmt);
|
remove_stmt_from_eh_lp_fn (cfun, stmt);
|
||||||
record_stmt_eh_region (region, stmt);
|
record_stmt_eh_region (region, stmt);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ERT_TRY:
|
case ERT_MUST_NOT_THROW:
|
||||||
if (match_lp (region, &exception_types)) {
|
// Undefined behavior, leave edge unchanged
|
||||||
if (!update)
|
return;
|
||||||
return;
|
|
||||||
if (gimple_code (stmt) == GIMPLE_RESX){
|
|
||||||
unlink_eh_region (resx_region);
|
|
||||||
reinsert_eh_region (resx_region, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_stmt_from_eh_lp_fn (cfun, stmt);
|
case ERT_ALLOWED_EXCEPTIONS:
|
||||||
record_stmt_eh_region (region, stmt);
|
/* FIXME: match_lp will always return false. */
|
||||||
return;
|
if (!match_lp (region, &exception_types))
|
||||||
}
|
{
|
||||||
break;
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ERT_MUST_NOT_THROW:
|
default:
|
||||||
// Undefined behavior, leave edge unchanged
|
break;
|
||||||
return;
|
|
||||||
|
|
||||||
case ERT_ALLOWED_EXCEPTIONS:
|
|
||||||
/* FIXME: match_lp will always return false. */
|
|
||||||
if (!match_lp (region, &exception_types)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
region = region->outer;
|
region = region->outer;
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!update)
|
if (!update)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (gimple_code (stmt) == GIMPLE_RESX){
|
if (gimple_code (stmt) == GIMPLE_RESX)
|
||||||
|
{
|
||||||
unlink_eh_region (resx_region);
|
unlink_eh_region (resx_region);
|
||||||
reinsert_eh_region (resx_region, NULL);
|
reinsert_eh_region (resx_region, NULL);
|
||||||
}
|
}
|
||||||
remove_stmt_from_eh_lp_fn (cfun, stmt);
|
remove_stmt_from_eh_lp_fn (cfun, stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the single EH edge from STMT to its nearest landing pad,
|
/* Create the single EH edge from STMT to its nearest landing pad,
|
||||||
|
|
@ -3091,91 +3124,114 @@ stmt_could_throw_1_p (gassign *stmt)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool extract_types_for_call (gcall *call_stmt, vec<tree> *ret_vector) {
|
bool
|
||||||
tree callee = gimple_call_fndecl (call_stmt);
|
extract_types_for_call (gcall *call_stmt, vec<tree> *ret_vector)
|
||||||
if (callee == NULL_TREE) {
|
{
|
||||||
return false;
|
tree callee = gimple_call_fndecl (call_stmt);
|
||||||
|
if (callee == NULL_TREE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0) {
|
if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0)
|
||||||
// Extracting exception type
|
{
|
||||||
tree exception_type_info = gimple_call_arg (call_stmt, 1);
|
// Extracting exception type
|
||||||
if (exception_type_info && TREE_CODE (exception_type_info) == ADDR_EXPR) {
|
tree exception_type_info = gimple_call_arg (call_stmt, 1);
|
||||||
exception_type_info = TREE_OPERAND (exception_type_info, 0);
|
if (exception_type_info && TREE_CODE (exception_type_info) == ADDR_EXPR)
|
||||||
|
{
|
||||||
|
exception_type_info = TREE_OPERAND (exception_type_info, 0);
|
||||||
}
|
}
|
||||||
if (exception_type_info && TREE_CODE (exception_type_info) == VAR_DECL) {
|
if (exception_type_info && TREE_CODE (exception_type_info) == VAR_DECL)
|
||||||
// Converting the typeinfo to a compile-time type
|
{
|
||||||
tree exception_type = TREE_TYPE (decl_assembler_name (exception_type_info));
|
// Converting the typeinfo to a compile-time type
|
||||||
if (exception_type) {
|
tree exception_type
|
||||||
ret_vector->safe_push (exception_type);
|
= TREE_TYPE (decl_assembler_name (exception_type_info));
|
||||||
|
if (exception_type)
|
||||||
|
{
|
||||||
|
ret_vector->safe_push (exception_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine which types can be thrown by a GIMPLE statement and convert them to compile-time types
|
/* Determine which types can be thrown by a GIMPLE statement and convert them
|
||||||
bool stmt_throw_types (function *fun, gimple *stmt, vec<tree> *ret_vector) {
|
* to compile-time types */
|
||||||
if (!flag_exceptions) {
|
bool
|
||||||
return false;
|
stmt_throw_types (function *, gimple *stmt, vec<tree> *ret_vector)
|
||||||
|
{
|
||||||
|
if (!flag_exceptions)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
bool type_exists = true;
|
bool type_exists = true;
|
||||||
|
|
||||||
switch (gimple_code (stmt)) {
|
switch (gimple_code (stmt))
|
||||||
case GIMPLE_RESX:
|
{
|
||||||
type_exists = extract_types_for_resx (as_a<gresx*> (stmt), ret_vector);
|
case GIMPLE_RESX:
|
||||||
return type_exists;
|
type_exists = extract_types_for_resx (as_a<gresx *> (stmt), ret_vector);
|
||||||
|
return type_exists;
|
||||||
|
|
||||||
case GIMPLE_CALL:
|
case GIMPLE_CALL:
|
||||||
type_exists = extract_types_for_call (as_a<gcall*> (stmt), ret_vector);
|
type_exists = extract_types_for_call (as_a<gcall *> (stmt), ret_vector);
|
||||||
/* FIXME: if type exists we should have always vector nonempty. */
|
/* FIXME: if type exists we should have always vector nonempty. */
|
||||||
return type_exists && !ret_vector->is_empty ();
|
return type_exists && !ret_vector->is_empty ();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// To get the all exception types from a resx stmt
|
// To get the all exception types from a resx stmt
|
||||||
static bool extract_types_for_resx (basic_block bb, vec<tree> *ret_vector) {
|
static bool
|
||||||
edge e;
|
extract_types_for_resx (basic_block bb, vec<tree> *ret_vector)
|
||||||
edge_iterator ei;
|
{
|
||||||
|
edge e;
|
||||||
|
edge_iterator ei;
|
||||||
|
|
||||||
// Iterate over edges to walk up the basic blocks
|
// Iterate over edges to walk up the basic blocks
|
||||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||||
{
|
{
|
||||||
// Get the last stmt of the basic block as it is an EH stmt
|
// Get the last stmt of the basic block as it is an EH stmt
|
||||||
bb = e->src;
|
bb = e->src;
|
||||||
gimple_stmt_iterator gsi = gsi_last_bb (bb);
|
gimple_stmt_iterator gsi = gsi_last_bb (bb);
|
||||||
gimple *last_stmt = gsi_stmt (gsi);
|
gimple *last_stmt = gsi_stmt (gsi);
|
||||||
|
|
||||||
if (bb->aux)continue;
|
if (bb->aux)
|
||||||
bb->aux = (void*)1;
|
continue;
|
||||||
|
bb->aux = (void *)1;
|
||||||
if (last_stmt && (e->flags & EDGE_EH)){
|
|
||||||
if (gimple_code (last_stmt) == GIMPLE_CALL) {
|
if (last_stmt && (e->flags & EDGE_EH))
|
||||||
// check if its a throw
|
{
|
||||||
if (!extract_types_for_call (as_a<gcall*> (last_stmt), ret_vector))
|
if (gimple_code (last_stmt) == GIMPLE_CALL)
|
||||||
return false;
|
{
|
||||||
continue;
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (gimple_code (last_stmt) == GIMPLE_RESX){
|
|
||||||
// Recursively processing resx
|
|
||||||
extract_types_for_resx (last_stmt, ret_vector);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/* FIXME: remove recursion here, so we do not run out of stack. */
|
/* FIXME: remove recursion here, so we do not run out of stack. */
|
||||||
else if (!extract_types_for_resx (last_stmt, ret_vector))
|
else if (!extract_types_for_resx (e->src, ret_vector))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// To get the all exception types from a resx stmt
|
// To get the all exception types from a resx stmt
|
||||||
bool extract_types_for_resx (gimple *resx_stmt, vec<tree> *ret_vector) {
|
bool
|
||||||
|
extract_types_for_resx (gimple *resx_stmt, vec<tree> *ret_vector)
|
||||||
|
{
|
||||||
basic_block bb = gimple_bb (resx_stmt);
|
basic_block bb = gimple_bb (resx_stmt);
|
||||||
bool ret = extract_types_for_resx (bb, ret_vector);
|
bool ret = extract_types_for_resx (bb, ret_vector);
|
||||||
/* FIXME: this is non-linear. */
|
/* FIXME: this is non-linear. */
|
||||||
|
|
@ -3184,40 +3240,48 @@ bool extract_types_for_resx (gimple *resx_stmt, vec<tree> *ret_vector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// To get the types being thrown outside of a function
|
// To get the types being thrown outside of a function
|
||||||
bool extract_fun_resx_types (function *fun, vec<tree> *ret_vector) {
|
bool
|
||||||
basic_block bb;
|
extract_fun_resx_types (function *fun, vec<tree> *ret_vector)
|
||||||
gimple_stmt_iterator gsi;
|
{
|
||||||
|
basic_block bb;
|
||||||
|
gimple_stmt_iterator gsi;
|
||||||
hash_set<tree> types;
|
hash_set<tree> types;
|
||||||
|
|
||||||
FOR_EACH_BB_FN (bb, fun)
|
FOR_EACH_BB_FN (bb, fun)
|
||||||
{
|
{
|
||||||
bb->aux = (void*)1;
|
bb->aux = (void *)1;
|
||||||
gsi = gsi_last_bb (bb);
|
gsi = gsi_last_bb (bb);
|
||||||
gimple *stmt = gsi_stmt (gsi);
|
gimple *stmt = gsi_stmt (gsi);
|
||||||
auto_vec<tree> resx_types;
|
auto_vec<tree> resx_types;
|
||||||
|
|
||||||
if (!stmt || !stmt_can_throw_external (fun, stmt))
|
if (!stmt || !stmt_can_throw_external (fun, stmt))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (gimple_code (stmt) == GIMPLE_RESX){
|
|
||||||
if (!extract_types_for_resx (stmt, &resx_types))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (gimple_code (stmt) == GIMPLE_CALL){
|
|
||||||
if (!extract_types_for_call (as_a<gcall*> (stmt), &resx_types))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned i = 0;i<resx_types.length ();++i){
|
if (gimple_code (stmt) == GIMPLE_RESX)
|
||||||
tree type = resx_types[i];
|
{
|
||||||
types.add (type);
|
if (!extract_types_for_resx (stmt, &resx_types))
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = types.begin (); it != types.end (); ++it) {
|
else if (gimple_code (stmt) == GIMPLE_CALL)
|
||||||
ret_vector->safe_push (*it);
|
{
|
||||||
|
if (!extract_types_for_call (as_a<gcall *> (stmt), &resx_types))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < resx_types.length (); ++i)
|
||||||
|
{
|
||||||
|
tree type = resx_types[i];
|
||||||
|
types.add (type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto it = types.begin (); it != types.end (); ++it)
|
||||||
|
{
|
||||||
|
ret_vector->safe_push (*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if statement STMT within FUN could throw an exception. */
|
/* Return true if statement STMT within FUN could throw an exception. */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue