https://gcc.gnu.org/g:5f1a438ba69b855103cec32eecde60fd7e4415b0
commit 5f1a438ba69b855103cec32eecde60fd7e4415b0 Author: Pranil Dey <mkd...@gmail.com> Date: Tue Oct 1 10:00:59 2024 +0530 Added functions extract_fun_resx_types Diff: --- gcc/tree-eh.cc | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 8e7629164b7d..89640c0faf6d 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -49,6 +49,8 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "print-tree.h" #include "ipa-utils.h" +#include "print-tree.h" +#include "ipa-utils.h" #include "hash-set.h" /* In some instances a tree and a gimple need to be stored in a same table, @@ -2275,6 +2277,106 @@ make_eh_dispatch_edges (geh_dispatch *stmt) } bool same_or_derived_type (tree t1, tree t2) +{ + t1 = TYPE_MAIN_VARIANT (t1); + t2 = TYPE_MAIN_VARIANT (t2); + if (t1 == t2) + return true; + while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) + && TREE_CODE (t1) == TREE_CODE (t2)) + { + t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); + t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); + } + if (t1 == t2) + return true; + if (!AGGREGATE_TYPE_P (t1) || !AGGREGATE_TYPE_P (t2)) + return false; + return odr_equivalent_or_derived_p (t1, t2); +} + +// Check if a landing pad can handle any of the given exception types +bool match_lp(eh_landing_pad lp, vec<tree> *exception_types) { + eh_region region = lp->region; + + // 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) { + tree type_list = catch_handler->type_list; + + if (!type_list) + return true; + + for (tree t = type_list; t; t = TREE_CHAIN(t)) { + tree type = TREE_VALUE(t); + for (unsigned i = 0; i < exception_types->length(); ++i) { + // match found or a catch-all handler (NULL) + if (!type || same_or_derived_type ((*exception_types)[i], type)) { + return true; + } + } + } + catch_handler = catch_handler->next_catch; + } + } + return false; +} + +// Function to update landing pad 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; + } + + eh_landing_pad lp = get_eh_landing_pad_from_number(lp_nr); + if (!lp) { + return; + } + + eh_region region = lp->region; + + // Walk up the region tree + while (region) { + switch (region->type) { + case ERT_CLEANUP: + *cfun->eh->throw_stmt_table->get(const_cast<gimple *>(stmt)) = lp->index; + return; + + case ERT_TRY: + if (match_lp(lp, &exception_types)) { + *cfun->eh->throw_stmt_table->get(const_cast<gimple *>(stmt)) = lp->index; + return; + } + break; + + case ERT_MUST_NOT_THROW: + // Undefined behavior, leave edge unchanged + return; + + case ERT_ALLOWED_EXCEPTIONS: + if (!match_lp(lp, &exception_types)) { + return; + } + break; + + default: + break; + } + region = region->outer; + } + + remove_stmt_from_eh_lp_fn(cfun, stmt); +} +bool +same_or_derived_type (tree t1, tree t2) { t1 = TYPE_MAIN_VARIANT (t1); t2 = TYPE_MAIN_VARIANT (t2); @@ -3029,6 +3131,42 @@ stmt_could_throw_1_p (gassign *stmt) return false; } +void extract_exception_types_for_call (gcall *call_stmt, vec<tree> *ret_vector) { + tree callee = gimple_call_fndecl (call_stmt); + if (callee == NULL_TREE) { + return; + } + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0) { + // Extracting exception type + tree exception_type_info = gimple_call_arg (call_stmt, 1); + 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) { + // Converting the typeinfo to a compile-time type + tree exception_type = TREE_TYPE (exception_type_info); + if (exception_type) { + ret_vector->safe_push (exception_type); + } + } + } +} + +// Determine which types can be thrown by a GIMPLE statement and convert them to compile-time types +bool stmt_throw_types (function *fun, gimple *stmt, vec<tree> *ret_vector) { + if (!flag_exceptions) { + return false; + } + + switch (gimple_code (stmt)) { + case GIMPLE_CALL: + extract_exception_types_for_call (as_a<gcall*> (stmt), ret_vector); + return !ret_vector->is_empty (); + + default: + return false; + } +} void extract_types_for_call (gcall *call_stmt, vec<tree> *ret_vector) { tree callee = gimple_call_fndecl (call_stmt); if (callee == NULL_TREE) {