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]>
---
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.