Skip to content

Commit 38eb2b1

Browse files
committed
More test scenarios for dead Gd<T> objects
1 parent ed4f24d commit 38eb2b1

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

itest/rust/src/object_tests/object_test.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,51 @@ fn object_user_free_during_bind() {
237237
obj.free(); // now succeeds
238238
}
239239

240+
#[itest]
241+
fn object_engine_freed_argument_passing(ctx: &TestContext) {
242+
let node: Gd<Node> = Node::new_alloc();
243+
244+
let mut tree = ctx.scene_tree.clone();
245+
let node2 = node.clone();
246+
247+
// Destroy object and then pass it to a Godot engine API.
248+
node.free();
249+
expect_panic("pass freed Gd<T> to Godot engine API (T=Node)", || {
250+
tree.add_child(node2);
251+
});
252+
}
253+
254+
#[itest]
255+
fn object_user_freed_casts() {
256+
let obj = Gd::from_object(ObjPayload {});
257+
let obj2 = obj.clone();
258+
let base_obj = obj.clone().upcast::<Object>();
259+
260+
// Destroy object and then pass it to a Godot engine API (upcast itself works, see other tests).
261+
obj.free();
262+
expect_panic("Gd<T>::upcast() on dead object (T=user)", || {
263+
let _ = obj2.upcast::<Object>();
264+
});
265+
expect_panic("Gd<T>::cast() on dead object (T=user)", || {
266+
let _ = base_obj.cast::<ObjPayload>();
267+
});
268+
}
269+
270+
#[itest]
271+
fn object_user_freed_argument_passing() {
272+
let obj = Gd::from_object(ObjPayload {});
273+
let obj = obj.upcast::<Object>();
274+
let obj2 = obj.clone();
275+
276+
let mut engine = Engine::singleton();
277+
278+
// Destroy object and then pass it to a Godot engine API (upcast itself works, see other tests).
279+
obj.free();
280+
expect_panic("pass freed Gd<T> to Godot engine API (T=user)", || {
281+
engine.register_singleton("NeverRegistered".into(), obj2);
282+
});
283+
}
284+
240285
#[itest(skip)] // This deliberately crashes the engine. Un-skip to manually test this.
241286
fn object_user_dynamic_free_during_bind() {
242287
// Note: we could also test if GDScript can access free() when an object is bound, to check whether the panic is handled or crashes

0 commit comments

Comments
 (0)