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