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 &param_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

Reply via email to