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
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index df90d1b..e62fed9 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -3183,60 +3183,59 @@
     }
 }
 
-// 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