https://gcc.gnu.org/g:f5b29909d5dd42299bc1eafff18211425266f791

commit f5b29909d5dd42299bc1eafff18211425266f791
Author: Pranil Dey <mkd...@gmail.com>
Date:   Sun Oct 6 18:25:17 2024 +0530

    Added function bool extract_types_for_resx and fixed more functions for 
testcases
    
    1. bool extract_types_for_resx (gimple *,vec<tree> *) - This is for 
intiating the function static bool extract_types_for_resx (basic_block, 
vec<tree> *)
    which gets the resx stmt from a basic block and aclears the aux value for 
all blocks
    2. update_stmt_eh_region - This is changed to unlink and reinsert the 
regions incase of a resx stmt properly

Diff:
---
 gcc/tree-eh.cc | 122 +++++++++++++++++++++++++++++----------------------------
 gcc/tree-eh.h  |   8 +---
 2 files changed, 65 insertions(+), 65 deletions(-)

diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index 89daf32046e3..634f33f9a8d9 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -2276,7 +2276,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt)
   return true;
 }
 
-bool
+static bool
 same_or_derived_type (tree t1, tree t2)
 {
   t1 = TYPE_MAIN_VARIANT (t1);
@@ -2288,18 +2288,20 @@ same_or_derived_type (tree t1, tree t2)
   {
     t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1));
     t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2));
+    if (TREE_CODE (t1) == VOID_TYPE)
+      return true;
   }
   if (t1 == t2)
     return true;
+  if (TREE_CODE (t2) == NULLPTR_TYPE && TREE_CODE (t1) == POINTER_TYPE)
+    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;
-
+static bool match_lp (eh_region region, vec<tree> *exception_types){
     // 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;
@@ -2315,7 +2317,7 @@ bool match_lp (eh_landing_pad lp, vec<tree> 
*exception_types) {
                 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)) {
+                    if (!type || same_or_derived_type (type, 
(*exception_types)[i])) {
                         return true;
                     }
                 }
@@ -2326,7 +2328,7 @@ bool match_lp (eh_landing_pad lp, vec<tree> 
*exception_types) {
     return false;
 }
 
-void unlink_eh_region(eh_region region) {
+static void unlink_eh_region(eh_region region) {
     eh_region *link;
 
     // Check if region is root
@@ -2350,8 +2352,7 @@ void unlink_eh_region(eh_region region) {
     region->next_peer = NULL;
 }
 
-void reinsert_eh_region (eh_region region, eh_landing_pad lp) {
-    eh_region new_outer = lp->region;
+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
@@ -2363,9 +2364,6 @@ void reinsert_eh_region (eh_region region, eh_landing_pad 
lp) {
         cfun->eh->region_tree = region;
     }
 
-    // Set the region index in the region array
-    region->index = vec_safe_length (cfun->eh->region_array);
-    vec_safe_push (cfun->eh->region_array, region);
 }
 
 // Function to update landing pad and region in throw_stmt_table for a given 
statement
@@ -2377,7 +2375,7 @@ void update_stmt_eh_region (gimple *stmt) {
     
     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);
@@ -2386,11 +2384,11 @@ void update_stmt_eh_region (gimple *stmt) {
     }
 
     eh_region region = lp->region;
-    eh_region prev_region = NULL;
+    eh_region resx_region = NULL;
 
     bool update = false;
     if (gimple_code (stmt) == GIMPLE_RESX)
-    region = region->outer;
+    resx_region = get_eh_region_from_number (gimple_resx_region (as_a <gresx 
*>  (stmt)));
 
     // Walk up the region tree
     while (region) {
@@ -2400,30 +2398,25 @@ void update_stmt_eh_region (gimple *stmt) {
                      return;
 
                 if (gimple_code (stmt) == GIMPLE_RESX){
-                  gresx *resx_stmt = as_a <gresx *> (stmt);
-                  gimple_resx_set_region (resx_stmt, region->index);
+                  unlink_eh_region (resx_region);
+                  reinsert_eh_region (resx_region, region);
                 }
 
-                else *cfun->eh->throw_stmt_table->get (const_cast<gimple *> 
(stmt)) = lp->index;
-
-                unlink_eh_region (region);
-                reinsert_eh_region (region, lp);
+                remove_stmt_from_eh_lp_fn (cfun, stmt);
+                record_stmt_eh_region (region, stmt);
                 return;
 
             case ERT_TRY:
-                if (update)
-                return;
-
-                if (match_lp (lp, &exception_types)) {
+                if (match_lp (region, &exception_types)) {
+                  if (!update)
+                  return;
                   if (gimple_code (stmt) == GIMPLE_RESX){
-                    gresx *resx_stmt = as_a <gresx *> (stmt);
-                    gimple_resx_set_region (resx_stmt, region->index);
+                    unlink_eh_region (resx_region);
+                    reinsert_eh_region (resx_region, region);
                   }
 
-                  else *cfun->eh->throw_stmt_table->get (const_cast<gimple *> 
(stmt)) = lp->index;
-
-                  unlink_eh_region (region);
-                  reinsert_eh_region (region, lp);
+                  remove_stmt_from_eh_lp_fn (cfun, stmt);
+                  record_stmt_eh_region (region, stmt);
                   return;
                 }
                 break;
@@ -2433,7 +2426,8 @@ void update_stmt_eh_region (gimple *stmt) {
                 return;
 
             case ERT_ALLOWED_EXCEPTIONS:
-                if (!match_lp (lp, &exception_types)) {
+            /* FIXME: match_lp will always return false.  */
+                if (!match_lp (region, &exception_types)) {
                     return;
                 }
                 break;
@@ -2441,7 +2435,6 @@ void update_stmt_eh_region (gimple *stmt) {
             default:
                 break;
         }
-        prev_region = region;
         region = region->outer;
         update = true;
     }
@@ -2450,10 +2443,10 @@ void update_stmt_eh_region (gimple *stmt) {
     return;
 
     if (gimple_code (stmt) == GIMPLE_RESX){
-      gresx *resx_stmt = as_a <gresx *> (stmt);
-      gimple_resx_set_region (resx_stmt, 0);
+      unlink_eh_region (resx_region);
+      reinsert_eh_region (resx_region, NULL);
     }
-    else 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,
@@ -3112,14 +3105,14 @@ bool extract_types_for_call (gcall *call_stmt, 
vec<tree> *ret_vector) {
         }
         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);
+            tree 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;
 }
 
 // Determine which types can be thrown by a GIMPLE statement and convert them 
to compile-time types
@@ -3131,11 +3124,12 @@ bool stmt_throw_types (function *fun, gimple *stmt, 
vec<tree> *ret_vector) {
 
     switch (gimple_code (stmt)) {
         case GIMPLE_RESX:
-            extract_fun_resx_types (fun, ret_vector);
-            return !ret_vector->is_empty ();
+            type_exists = extract_types_for_resx (as_a<gresx*> (stmt), 
ret_vector);
+            return type_exists;
 
         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.  */
             return type_exists && !ret_vector->is_empty ();
           
         default:
@@ -3143,13 +3137,11 @@ bool stmt_throw_types (function *fun, gimple *stmt, 
vec<tree> *ret_vector) {
     }
 }
 
-// To get the all exception types from a resx stmt  
-void extract_types_for_resx (gimple *resx_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;
        
-  basic_block bb = gimple_bb (resx_stmt);
-       
   // Iterate over edges to walk up the basic blocks
   FOR_EACH_EDGE (e, ei, bb->preds)
   {
@@ -3161,10 +3153,11 @@ void extract_types_for_resx (gimple *resx_stmt, 
vec<tree> *ret_vector) {
          if (bb->aux)continue;
          bb->aux = (void*)1;
        
-         if (!last_stmt && (e->flags & EDGE_EH)){
+         if (last_stmt && (e->flags & EDGE_EH)){
       if (gimple_code (last_stmt) == GIMPLE_CALL) {
         // check if its a throw
-        extract_types_for_call (as_a<gcall*> (last_stmt), ret_vector);
+        if (!extract_types_for_call (as_a<gcall*> (last_stmt), ret_vector))
+          return false;
         continue;
       }
       else if (gimple_code (last_stmt) == GIMPLE_RESX){
@@ -3174,18 +3167,28 @@ void extract_types_for_resx (gimple *resx_stmt, 
vec<tree> *ret_vector) {
       }
        
     }
-       else extract_types_for_resx (last_stmt, ret_vector);
+    /* FIXME: remove recursion here, so we do not run out of stack.  */
+       else if (!extract_types_for_resx (last_stmt, ret_vector))
+      return false;
   }
+  return true;
+}
+
+// To get the all exception types from a resx stmt  
+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;
 }
 
 // To get the types being thrown outside of a function
-void extract_fun_resx_types (function *fun, vec<tree> *ret_vector) {
+bool extract_fun_resx_types (function *fun, vec<tree> *ret_vector) {
        basic_block bb;
        gimple_stmt_iterator gsi;
   hash_set<tree> types;
 
-  clear_aux_for_blocks ();
-
        FOR_EACH_BB_FN (bb, fun)
        {
                bb->aux = (void*)1;
@@ -3193,14 +3196,17 @@ void extract_fun_resx_types (function *fun, vec<tree> 
*ret_vector) {
                gimple *stmt = gsi_stmt (gsi);
                auto_vec<tree> resx_types;
 
-               if (!stmt && stmt_can_throw_external (fun, stmt)){
-                       if (gimple_code (stmt) == GIMPLE_RESX){
-                               extract_types_for_resx (stmt, &resx_types);
-                       }
+    if (!stmt || !stmt_can_throw_external (fun, stmt))
+    continue;
+               
+               if (gimple_code (stmt) == GIMPLE_RESX){
+                       if (!extract_types_for_resx (stmt, &resx_types))
+        return false;
+               }
                        
-                       else if (gimple_code (stmt) == GIMPLE_CALL){
-                               extract_types_for_call (as_a<gcall*> (stmt), 
&resx_types);
-                       }
+               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){
@@ -3212,8 +3218,6 @@ void extract_fun_resx_types (function *fun, vec<tree> 
*ret_vector) {
   for (auto it = types.begin (); it != types.end (); ++it) {
         ret_vector->safe_push (*it);
   }
-
-  clear_aux_for_blocks ();
 }
 
 /* Return true if statement STMT within FUN could throw an exception.  */
diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h
index eebcecbce57d..d98c5cb527f3 100644
--- a/gcc/tree-eh.h
+++ b/gcc/tree-eh.h
@@ -32,10 +32,6 @@ extern bool remove_stmt_from_eh_lp (gimple *);
 extern int lookup_stmt_eh_lp_fn (struct function *, const gimple *);
 extern int lookup_stmt_eh_lp (const gimple *);
 extern bool make_eh_dispatch_edges (geh_dispatch *);
-extern bool same_or_derived_type (tree, tree);
-extern bool match_lp (eh_landing_pad, vec<tree> *);
-extern void unlink_eh_region(eh_region , eh_region);
-extern void reinsert_eh_region(eh_region , eh_landing_pad);
 extern void update_stmt_eh_region(gimple *);
 extern edge make_eh_edge (gimple *);
 extern edge redirect_eh_edge (edge, basic_block);
@@ -47,8 +43,8 @@ extern bool tree_could_trap_p (tree);
 extern tree rewrite_to_non_trapping_overflow (tree);
 extern bool extract_types_for_call (gcall *, vec<tree> *);
 extern bool stmt_throw_types (function *, gimple *, vec<tree> *);
-extern void extract_types_for_resx (gimple *, vec<tree> *);
-extern void extract_fun_resx_types (function *, vec<tree> *);
+extern bool extract_types_for_resx (gimple *, vec<tree> *);
+extern bool extract_fun_resx_types (function *, vec<tree> *);
 extern bool stmt_could_throw_p (function *, gimple *);
 extern bool stmt_unremovable_because_of_non_call_eh_p (function *, gimple *);
 extern bool tree_could_throw_p (tree);

Reply via email to