https://gcc.gnu.org/g:270f1230c18a01f5ec55bee44cde7dc3e065267a
commit r17-3091-g270f1230c18a01f5ec55bee44cde7dc3e065267a Author: Lishin <[email protected]> Date: Fri Jun 19 21:35:20 2026 +0000 gccrs: Emit drops for function parameters 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]> Diff: --- gcc/rust/backend/rust-compile-base.cc | 13 +++++- gcc/testsuite/rust/execute/drop-function-params.rs | 52 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 4e618243b3b3..04696787e407 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 000000000000..c538922f5c94 --- /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
