[gccrs,COMMIT,2/2] gccrs: Emit drops for function parameters

Message ID 20260708100618.3141-2-gerris.rs@gmail.com
State New
Headers
Series [gccrs,COMMIT,1/2] gccrs: Emit function-scope drops for unit tail expressions |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap fail Build failed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed

Commit Message

gerris.rs@gmail.com July 8, 2026, 10:06 a.m. UTC
  From: Lishin <lishin1008@gmail.com>

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 <lishin1008@gmail.com>
---
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/76397e896150e3bf04567fc8df45ef780df4e501

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/4591

 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
  

Patch

diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 4e618243b..04696787e 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 000000000..c538922f5
--- /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