diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h index b824044b82d..5afdb884f66 100644 --- a/core/variant/variant_construct.h +++ b/core/variant/variant_construct.h @@ -153,11 +153,14 @@ public: class VariantConstructorObject { public: static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); if (p_args[0]->get_type() == Variant::NIL) { + VariantInternal::clear(&r_ret); + VariantTypeChanger::change(&r_ret); VariantInternal::object_assign_null(&r_ret); r_error.error = Callable::CallError::CALL_OK; } else if (p_args[0]->get_type() == Variant::OBJECT) { + VariantInternal::clear(&r_ret); + VariantTypeChanger::change(&r_ret); VariantInternal::object_assign(&r_ret, p_args[0]); r_error.error = Callable::CallError::CALL_OK; } else { @@ -169,6 +172,7 @@ public: static inline void validated_construct(Variant *r_ret, const Variant **p_args) { VariantInternal::clear(r_ret); + VariantTypeChanger::change(r_ret); VariantInternal::object_assign(r_ret, p_args[0]); } static void ptr_construct(void *base, const void **p_args) { @@ -198,11 +202,13 @@ public: } VariantInternal::clear(&r_ret); + VariantTypeChanger::change(&r_ret); VariantInternal::object_assign_null(&r_ret); } static inline void validated_construct(Variant *r_ret, const Variant **p_args) { VariantInternal::clear(r_ret); + VariantTypeChanger::change(r_ret); VariantInternal::object_assign_null(r_ret); } static void ptr_construct(void *base, const void **p_args) { diff --git a/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd new file mode 100644 index 00000000000..3724c8c7130 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd @@ -0,0 +1,9 @@ +# https://github.com/godotengine/godot/issues/90086 + +class MyObj: + var obj: WeakRef + +func test(): + var obj_1 = MyObj.new() + var obj_2 = MyObj.new() + obj_1.obj = obj_2 diff --git a/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out new file mode 100644 index 00000000000..dfca5b1eca3 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out @@ -0,0 +1,6 @@ +GDTEST_RUNTIME_ERROR +>> SCRIPT ERROR +>> on function: test() +>> runtime/errors/invalid_property_assignment.gd +>> 9 +>> Invalid assignment of property or key 'obj' with value of type 'RefCounted (MyObj)' on a base object of type 'RefCounted (MyObj)'. diff --git a/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd new file mode 100644 index 00000000000..e1aba835072 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd @@ -0,0 +1,11 @@ +# https://github.com/godotengine/godot/issues/90086 + +class MyObj: + var obj : WeakRef + +func test(): + var obj_1 = MyObj.new() + var obj_2 = MyObj.new() + assert(obj_2.get_reference_count() == 1) + obj_1.set(&"obj", obj_2) + assert(obj_2.get_reference_count() == 1) diff --git a/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out new file mode 100644 index 00000000000..d73c5eb7cde --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out @@ -0,0 +1 @@ +GDTEST_OK