From: Lishin <[email protected]>
Add function parameters to the function scope drop list
after the function body block is created.
This makes parameters drop after local variables on normal function exit.
gcc/rust/ChangeLog:
* backend/rust-compile-base.cc (HIRCompileBase::compile_function):
Track droppable function parameters in the function scope.
gcc/testsuite/ChangeLog:
* rust/execute/drop-function-params.rs: New test.
Signed-off-by: Lishin <[email protected]>
---
gcc/rust/backend/rust-compile-base.cc | 13 ++++-
.../rust/execute/drop-function-params.rs | 52 +++++++++++++++++++
2 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/rust/execute/drop-function-params.rs
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 4e618243b3b..04696787e40 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -21,6 +21,7 @@
#include "rust-compile-stmt.h"
#include "rust-compile-expr.h"
#include "rust-compile-drop.h"
+#include "rust-compile-drop-builder.h"
#include "rust-compile-fnparam.h"
#include "rust-compile-var-decl.h"
#include "rust-compile-type.h"
@@ -739,7 +740,7 @@ HIRCompileBase::compile_function_body (tree fndecl,
// just add the stmt expression
ctx->add_statement (return_value);
- CompileDrop::emit_current_scope_drop_calls (ctx);
+ CompileDrop (ctx).emit_current_scope_drop_calls ();
// now just return unit expression
tree unit_expr = unit_expression (locus);
@@ -845,6 +846,7 @@ HIRCompileBase::compile_function (
// setup the params
TyTy::BaseType *tyret = fntype->get_return_type ();
std::vector<Bvariable *> param_vars;
+ std::vector<DropCandidate> param_drop_candidates;
if (self_param)
{
rust_assert (fntype->is_method ());
@@ -880,6 +882,11 @@ HIRCompileBase::compile_function (
const HIR::Pattern ¶m_pattern = referenced_param.get_param_name ();
ctx->insert_var_decl (param_pattern.get_mappings ().get_hirid (),
compiled_param_var);
+
+ if (CompileDrop (ctx).type_has_drop_impl (param_tyty))
+ param_drop_candidates.emplace_back (
+ param_pattern.get_mappings ().get_hirid (),
+ param_pattern.get_locus ());
}
if (!Backend::function_set_parameters (fndecl, param_vars))
@@ -893,6 +900,10 @@ HIRCompileBase::compile_function (
start_location, end_location);
ctx->push_block (code_block);
+ DropBuilder drop_builder (*ctx);
+ for (auto &candidate : param_drop_candidates)
+ drop_builder.note_simple_drop_candidate (candidate.hirid, candidate.locus);
+
Bvariable *return_address = nullptr;
tree return_type = TyTyResolveCompile::compile (ctx, tyret);
diff --git a/gcc/testsuite/rust/execute/drop-function-params.rs b/gcc/testsuite/rust/execute/drop-function-params.rs
new file mode 100644
index 00000000000..c538922f5c9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/drop-function-params.rs
@@ -0,0 +1,52 @@
+// { dg-output "l\r*\np\r*\nl\r*\np\r*\n" }
+// { dg-additional-options "-w" }
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "drop"]
+pub trait Drop {
+ fn drop(&mut self);
+}
+
+struct ParamDroppable;
+struct LocalDroppable;
+
+impl Drop for ParamDroppable {
+ fn drop(&mut self) {
+ let msg = "p\n\0" as *const str as *const i8;
+ unsafe {
+ printf(msg);
+ }
+ }
+}
+
+impl Drop for LocalDroppable {
+ fn drop(&mut self) {
+ let msg = "l\n\0" as *const str as *const i8;
+ unsafe {
+ printf(msg);
+ }
+ }
+}
+
+fn named_param(_p: ParamDroppable) {
+ let _l = LocalDroppable;
+}
+
+fn wildcard_param(_: ParamDroppable) {
+ let _l = LocalDroppable;
+}
+
+fn main() -> i32 {
+ named_param(ParamDroppable);
+ wildcard_param(ParamDroppable);
+ 0
+}
\ No newline at end of file
--
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.