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

commit d1a84d379d65c8d11a1f81e54f41d98cbce03cd7
Author: Pranil Dey <mkd...@gmail.com>
Date:   Sat Sep 21 03:06:48 2024 +0530

    RESX statement processing functions added:
    
    1. extract_types_for_resx - Used as a helper for getting the types from a 
resx statement to use later in the extract_fun_resx_types
    2. extract_fun_resx_types - Used for getting the types thrown and 
propagated outside a function

Diff:
---
 gcc/tree-eh.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index e7e4bd191628..121cbed505b8 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -3053,6 +3053,71 @@ 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) {
+       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->pred)
+  {
+       // 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 (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);
+        continue;
+      }
+      else if (gimple_code(last_stmt) == GIMPLE_RESX){
+        // Recursively processing resx
+        extract_types_for_resx (last_stmt, ret_vector);
+        continue;
+      }
+       
+    }
+       else extract_types_for_resx (last_stmt, ret_vector);
+  }
+}
+
+// To get the types being thrown outside of a function
+void extract_fun_resx_types (function *fun){
+       basic_block bb;
+       gimple_stmt_iterator gsi;
+       vec<tree> *exception_types;
+
+       FOR_EACH_BB_FN (bb, fun)
+       {
+               bb->aux = (void*)1;
+               gsi = gsi_last_bb (bb);
+               gimple *stmt = gsi_stmt (gsi);
+               vec<tree> *ret_vector;
+
+               if (stmt_can_throw_external (stmt)){
+                       if (gimple_code (stmt) == GIMPLE_RESX){
+                               extract_types_for_resx (stmt, ret_vector);
+                       }
+                       
+                       else if (gimple_code (stmt) == GIMPLE_CALL){
+                               extract_types_for_call (as_a<gcall*> (stmt), 
ret_vector);
+                       }
+               }
+
+               for (unsigned i = 0;i<ret_vector->length ();++i){
+                       tree type = (*ret_vector)[i];
+                       exception_types->safe_push (type);
+               }
+       }
+}
+
 /* Return true if statement STMT within FUN could throw an exception.  */
 
 bool

Reply via email to