[COMMITTED 37/77] gccrs: Emit block scope drops through TRY_FINALLY_EXPR

arthur.cohen@embecosm.com arthur.cohen@embecosm.com
Fri Aug 7 12:39:28 GMT 2026


From: Lishin <lishin1008@gmail.com>

Add Context::pop_block_with_cleanup for blocks that need cleanup.

Use it from CompileBlock so block-scope drops are emitted in a
TRY_FINALLY_EXPR cleanup instead of at the end of the block body.

gcc/rust/ChangeLog:

	* backend/rust-compile-block.cc
	(CompileBlock::visit): Build current scope drop cleanup and
	pass it when popping the block.
	* backend/rust-compile-context.h
	(Context::pop_block): Use pop_block_impl.
	(Context::pop_block_with_cleanup): New function for popping
	a block with cleanup code.
	(Context::pop_block_impl): New helper that adds the block
	statements directly, or wraps them in TRY_FINALLY_EXPR when
	cleanup is present.

Signed-off-by: Lishin <lishin1008@gmail.com>
---
 gcc/rust/backend/rust-compile-block.cc  |  4 +--
 gcc/rust/backend/rust-compile-context.h | 45 ++++++++++++++++++-------
 2 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc
index e35d02e52a0..ca69315c3b5 100644
--- a/gcc/rust/backend/rust-compile-block.cc
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -85,9 +85,9 @@ CompileBlock::visit (HIR::BlockExpr &expr)
 					 expr.get_locus ());
       ctx->add_statement (assignment);
     }
-  CompileDrop (ctx).emit_current_scope_drop_calls ();
+  tree cleanup = CompileDrop (ctx).build_current_scope_drop_cleanup ();
 
-  ctx->pop_block ();
+  ctx->pop_block_with_cleanup (cleanup, expr.get_locus ());
   translated = new_block;
 }
 
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 9fe39e5572d..25a27ca9628 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -107,20 +107,11 @@ public:
     block_drop_candidates.emplace_back ();
   }
 
-  tree pop_block ()
-  {
-    auto block = scope_stack.back ();
-    scope_stack.pop_back ();
-
-    auto stmts = statements.back ();
-    statements.pop_back ();
-
-    rust_assert (!block_drop_candidates.empty ());
-    block_drop_candidates.pop_back ();
+  tree pop_block () { return pop_block_impl (NULL_TREE, UNKNOWN_LOCATION); }
 
-    Backend::block_add_statements (block, stmts);
-
-    return block;
+  tree pop_block_with_cleanup (tree cleanup, location_t cleanup_locus)
+  {
+    return pop_block_impl (cleanup, cleanup_locus);
   }
 
   tree peek_enclosing_scope ()
@@ -429,6 +420,34 @@ private:
   friend class DropBuilder;
   Context ();
 
+  tree pop_block_impl (tree cleanup, location_t cleanup_locus)
+  {
+    auto block = scope_stack.back ();
+    scope_stack.pop_back ();
+
+    auto stmts = statements.back ();
+    statements.pop_back ();
+
+    rust_assert (!block_drop_candidates.empty ());
+    block_drop_candidates.pop_back ();
+
+    if (cleanup != NULL_TREE)
+      {
+	tree body = Backend::statement_list (stmts);
+	if (body == NULL_TREE)
+	  body = build_empty_stmt (cleanup_locus);
+
+	tree try_finally
+	  = Backend::exception_handler_statement (body, NULL_TREE, cleanup,
+						  cleanup_locus);
+	Backend::block_add_statements (block, {try_finally});
+      }
+    else
+      Backend::block_add_statements (block, stmts);
+
+    return block;
+  }
+
   Resolver::TypeCheckContext *tyctx;
   Analysis::Mappings &mappings;
   Mangler mangler;
-- 
2.50.1



More information about the Gcc-rust mailing list