diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 9e96d4b07941..d34ed2969143 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1733,7 +1733,36 @@ void _Thread::_start_func(void *ud) { memdelete(tud); Callable::CallError ce; const Variant *arg[1] = { &t->userdata }; - int argc = (int)(arg[0]->get_type() != Variant::NIL); + int argc = 0; + if (arg[0]->get_type() != Variant::NIL) { + // Just pass to the target function whatever came as user data + argc = 1; + } else { + // There are two cases of null user data: + // a) The target function has zero parameters and the caller is just honoring that. + // b) The target function has at least one parameter with no default and the caller is + // leveraging the fact that user data defaults to null in Thread.start(). + // We care about the case of more than one parameter because, even if a thread + // function can have one at most, out mindset here is to do our best with the + // only/first one and let the call handle any other error conditions, like too + // much arguments. + // We must check if we are in case b). + int target_param_count = 0; + int target_default_arg_count = 0; + Ref