Przeglądaj źródła

Merge pull request #90134 from AThousandShips/construct_fix

[Core] Fix `Variant::construct` of `Object`
Rémi Verschelde 1 rok temu
rodzic
commit
7805220fef

+ 7 - 1
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<Object *>::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<Object *>::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<Object *>::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<Object *>::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<Object *>::change(r_ret);
 		VariantInternal::object_assign_null(r_ret);
 	}
 	static void ptr_construct(void *base, const void **p_args) {

+ 9 - 0
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

+ 6 - 0
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)'.

+ 11 - 0
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)

+ 1 - 0
modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out

@@ -0,0 +1 @@
+GDTEST_OK