Fixed extract_types_for_resx function devel/nothrow-detection
authorPranil Dey <mkdeyp@gmail.com>
Thu, 24 Oct 2024 19:26:59 +0000 (00:56 +0530)
committerPranil Dey <mkdeyp@gmail.com>
Thu, 24 Oct 2024 19:27:07 +0000 (00:57 +0530)
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

gcc/tree-eh.cc

index df90d1bc2049d05354e77567bd8db36be49f8e19..e62fed90c6ddd47ea149d072bd005d25a429cbce 100644 (file)
@@ -3183,60 +3183,59 @@ stmt_throw_types (function *, gimple *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)
+// To get the all exception types from a resx stmt (iterative version)
+bool
+extract_types_for_resx (gimple *resx_stmt, vec<tree> *ret_vector)
 {
-  edge e;
-  edge_iterator ei;
+  basic_block start_bb = gimple_bb (resx_stmt);
+  hash_set<basic_block> visited_blocks;
+  vec<basic_block> block_stack;
 
-  // 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);
+  block_stack.safe_push(start_bb);
 
-    if (bb->aux)
+  while (!block_stack.is_empty())
+  {
+    basic_block bb = block_stack.pop();
+    if (visited_blocks.contains(bb))
       continue;
-    bb->aux = (void *)1;
 
-    if (last_stmt && (e->flags & EDGE_EH))
+    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)
       {
-        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;
-          }
+        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);
+        }
       }
-    /* FIXME: remove recursion here, so we do not run out of stack.  */
-    else if (!extract_types_for_resx (e->src, ret_vector))
-      return false;
+      else
+      {
+        block_stack.safe_push(pred_bb);
+      }
+    }
   }
-  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;
+  clear_aux_for_blocks();
+  return true;
 }
 
 // To get the types being thrown outside of a function
This page took 0.061682 seconds and 5 git commands to generate.