From: Lishin <[email protected]>

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 <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/f1ce54fea55aa83f1d239dd660324516c353a70d

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4685

 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 e35d02e52..ca69315c3 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 9fe39e557..25a27ca96 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.54.0

Reply via email to