https://gcc.gnu.org/g:133f8ce3e14c568ec2bc1ef45b028e56c31e017b
commit r17-4126-g133f8ce3e14c568ec2bc1ef45b028e56c31e017b Author: Lishin <[email protected]> Date: Sun Aug 16 09:56:11 2026 +0000 gccrs: Add execute tests for supported Drop behavior Add execute coverage for Drop behavior that is already supported but was not covered by the testsuite. Cover function parameter drop order, explicit returns, ownership transfers through function arguments and return values, and branch-local values. gcc/testsuite/ChangeLog: * rust/execute/drop-explicit-return.rs: Test parameter drops on explicit return. * rust/execute/drop-function-boundary-moves.rs: New test. * rust/execute/drop-function-params.rs: Test multiple parameter drop order. * rust/execute/drop-if-else-local.rs: New test. Diff: --- gcc/testsuite/rust/execute/drop-explicit-return.rs | 44 +++++++++++++++++- .../rust/execute/drop-function-boundary-moves.rs | 53 +++++++++++++++++++++ gcc/testsuite/rust/execute/drop-function-params.rs | 36 ++++++++++++++- gcc/testsuite/rust/execute/drop-if-else-local.rs | 54 ++++++++++++++++++++++ 4 files changed, 183 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/rust/execute/drop-explicit-return.rs b/gcc/testsuite/rust/execute/drop-explicit-return.rs index c138823f9abc..46595656ecb4 100644 --- a/gcc/testsuite/rust/execute/drop-explicit-return.rs +++ b/gcc/testsuite/rust/execute/drop-explicit-return.rs @@ -1,4 +1,4 @@ -// { dg-output "unit\r*\nmake_unit\r*\nunit_expr\r*\nmake_value\r*\nnonunit\r*\ninner\r*\nouter\r*\n" } +// { dg-output "^unit\r*\nmake_unit\r*\nunit_expr\r*\nmake_value\r*\nnonunit\r*\ninner\r*\nouter\r*\nreturn local\r*\nreturn p2\r*\nreturn p1\r*\n$" } // { dg-additional-options "-w" } #![feature(no_core)] #![feature(lang_items)] @@ -21,6 +21,15 @@ struct UnitExprDroppable; struct NonUnitDroppable; struct OuterDroppable; struct InnerDroppable; +struct ReturnFirstParam { + value: i32, +} +struct ReturnSecondParam { + value: i32, +} +struct ReturnLocal { + value: i32, +} impl Drop for UnitDroppable { fn drop(&mut self) { @@ -56,6 +65,27 @@ impl Drop for InnerDroppable { } } +impl Drop for ReturnFirstParam { + fn drop(&mut self) { + let msg = "return p1\n\0" as *const str as *const i8; + unsafe { printf(msg); } + } +} + +impl Drop for ReturnSecondParam { + fn drop(&mut self) { + let msg = "return p2\n\0" as *const str as *const i8; + unsafe { printf(msg); } + } +} + +impl Drop for ReturnLocal { + fn drop(&mut self) { + let msg = "return local\n\0" as *const str as *const i8; + unsafe { printf(msg); } + } +} + fn make_unit () { let msg = "make_unit\n\0" as *const str as *const i8; unsafe { printf(msg); } @@ -90,6 +120,11 @@ fn nested_return() { } } +fn parameter_return(_p1: ReturnFirstParam, _p2: ReturnSecondParam) { + let _local = ReturnLocal { value: 3 }; + return; +} + fn main() -> i32 { unit_return (); unit_return_expr (); @@ -101,5 +136,10 @@ fn main() -> i32 { nested_return(); + parameter_return( + ReturnFirstParam { value: 1 }, + ReturnSecondParam { value: 2 }, + ); + 0 -} \ No newline at end of file +} diff --git a/gcc/testsuite/rust/execute/drop-function-boundary-moves.rs b/gcc/testsuite/rust/execute/drop-function-boundary-moves.rs new file mode 100644 index 000000000000..afa8a387eb9b --- /dev/null +++ b/gcc/testsuite/rust/execute/drop-function-boundary-moves.rs @@ -0,0 +1,53 @@ +// { dg-output "^drop 1\r*\ndrop 2\r*\ndrop 3\r*\n$" } +// { dg-additional-options "-frust-borrowcheck -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 Droppable { + value: i32, +} + +impl Drop for Droppable { + fn drop(&mut self) { + let msg = "drop %d\n\0" as *const str as *const i8; + unsafe { + printf(msg, self.value); + } + } +} + +fn take(_value: Droppable) {} + +fn move_parameter(value: Droppable) { + let _moved = value; +} + +fn make() -> Droppable { + let value = Droppable { value: 3 }; + value +} + +fn main() -> i32 { + let value = Droppable { value: 1 }; + take(value); + + move_parameter(Droppable { value: 2 }); + + let _returned = make(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/drop-function-params.rs b/gcc/testsuite/rust/execute/drop-function-params.rs index c538922f5c94..6aabce4c9271 100644 --- a/gcc/testsuite/rust/execute/drop-function-params.rs +++ b/gcc/testsuite/rust/execute/drop-function-params.rs @@ -1,4 +1,4 @@ -// { dg-output "l\r*\np\r*\nl\r*\np\r*\n" } +// { dg-output "^l\r*\np\r*\nl\r*\np\r*\nl\r*\np2\r*\np1\r*\n$" } // { dg-additional-options "-w" } #![feature(no_core)] #![feature(lang_items)] @@ -18,6 +18,12 @@ pub trait Drop { struct ParamDroppable; struct LocalDroppable; +struct FirstParamDroppable { + value: i32, +} +struct SecondParamDroppable { + value: i32, +} impl Drop for ParamDroppable { fn drop(&mut self) { @@ -37,6 +43,24 @@ impl Drop for LocalDroppable { } } +impl Drop for FirstParamDroppable { + fn drop(&mut self) { + let msg = "p1\n\0" as *const str as *const i8; + unsafe { + printf(msg); + } + } +} + +impl Drop for SecondParamDroppable { + fn drop(&mut self) { + let msg = "p2\n\0" as *const str as *const i8; + unsafe { + printf(msg); + } + } +} + fn named_param(_p: ParamDroppable) { let _l = LocalDroppable; } @@ -45,8 +69,16 @@ fn wildcard_param(_: ParamDroppable) { let _l = LocalDroppable; } +fn multiple_params(_p1: FirstParamDroppable, _p2: SecondParamDroppable) { + let _l = LocalDroppable; +} + fn main() -> i32 { named_param(ParamDroppable); wildcard_param(ParamDroppable); + multiple_params( + FirstParamDroppable { value: 1 }, + SecondParamDroppable { value: 2 }, + ); 0 -} \ No newline at end of file +} diff --git a/gcc/testsuite/rust/execute/drop-if-else-local.rs b/gcc/testsuite/rust/execute/drop-if-else-local.rs new file mode 100644 index 000000000000..05afb2806194 --- /dev/null +++ b/gcc/testsuite/rust/execute/drop-if-else-local.rs @@ -0,0 +1,54 @@ +// { dg-output "^drop 1\r*\nafter\r*\ndrop 2\r*\nafter\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 Droppable { + value: i32, +} + +impl Drop for Droppable { + fn drop(&mut self) { + let msg = "drop %d\n\0" as *const str as *const i8; + unsafe { + printf(msg, self.value); + } + } +} + +fn droppable(value: i32) -> Droppable { + Droppable { value } +} + +fn test(condition: bool) { + if condition { + let _value = droppable(1); + } else { + let _value = droppable(2); + } + + let msg = "after\n\0" as *const str as *const i8; + unsafe { + printf(msg); + } +} + +fn main() -> i32 { + test(true); + test(false); + 0 +}
