-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GDScript: Set has_type
false if it is BUILTIN
but Variant::NIL
#88020
GDScript: Set has_type
false if it is BUILTIN
but Variant::NIL
#88020
Conversation
Plus I think it's worth adding a test. |
I have looked what is happening in I think the main problem is with |
Sorry, I was thinking that we could use Or, if look at it differently, GDScript has an implicit type |
I think the one you referring is this one https://docs.godotengine.org/en/3.1/classes/class_nil.html and probably it's the default version of Variant with default NIL type. My gut feeling says that only difference from the other types is just godot/core/variant/variant_utility.cpp Lines 1922 to 1929 in d335281
|
2e684ef
to
b0f8c06
Compare
modules/gdscript/tests/scripts/parser/features/match_test_null.gd
Outdated
Show resolved
Hide resolved
027d39a
to
47d0b50
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to solve it here:
godot/modules/gdscript/gdscript_byte_codegen.cpp
Line 1086 in b4e2a24
if (!IS_BUILTIN_TYPE(p_arguments[i], Variant::get_utility_function_argument_type(p_function, i))) { |
- if (!IS_BUILTIN_TYPE(p_arguments[i], Variant::get_utility_function_argument_type(p_function, i))) {
+ const Variant::Type arg_type = Variant::get_utility_function_argument_type(p_function, i);
+ // `Variant::get_utility_function_argument_type()` returns `Variant::NIL` for `Variant` arguments.
+ if (arg_type == Variant::NIL || !IS_BUILTIN_TYPE(p_arguments[i], arg_type)) {
We have some problem distinguishing between Nil
and Variant
(there is PROPERTY_USAGE_NIL_IS_VARIANT
). In some cases, Variant::NIL
is used as the default value, in others Variant::VARIANT_MAX
.
modules/gdscript/tests/scripts/parser/features/match_test_null.gd
Outdated
Show resolved
Hide resolved
47d0b50
to
8858b41
Compare
has_type
false if it is BUILTIN
but Variant::NIL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, but I'd appreciate a double check. We fixed the crash for now, but I'm not sure there aren't similar cases elsewhere. Perhaps we should change the IS_BUILTIN_TYPE
macro or use Variant::VARIANT_MAX
as the default value instead of Variant::NIL
.
Thanks, I'll check it again. I agree, it could be better to add it to godot/core/variant/variant_utility.cpp Lines 1922 to 1929 in d335281
I tried to trace the registered function but it got complicated quickly. I'll have a second look there and try to find out if it's better to return VARIANT_MAX .
|
8858b41
to
081fa32
Compare
I think that if a method has a https://github.com/godotengine/godot/blob/master/doc/classes/%40GlobalScope.xml#L1409-L1425 |
There's an extra problem here that we cannot properly validate the call if the argument is of type Variant, because the function itself might restrict which types are actually acceptable and there's no API to know that. In the case of The issue is that the crash is not even because it's trying to do a validated call. It crashes only because of this: godot/modules/gdscript/gdscript_byte_codegen.cpp Lines 1097 to 1098 in 5cf0d77
The target might not be always a temporary, so trying to access the temporaries' table might be bogus, which is exactly what happens with this crash. The code should check if it's actually a temporary or not before trying to get its type. I'm approving this because it "solves" the first point (as it won't emit validated calls when the argument is Variant), but the other point should be checked as well. |
Thanks! And congrats for your first merged Godot contribution 🎉 |
Thank you🙂 |
This change fixes #87932 by preventing edge case for null value when used with a match. Even though edge case is happening with third check in IS_BUILTIN_TYPE(),
m_var.type.builtin_type == m_type
, there is no other default type other than Variant::NIL, so this check wouldn't change. But returning false with has_type in the first check for Variant::NIL makes more sense since it is also the default value in GDScriptDataType.godot/modules/gdscript/gdscript_byte_codegen.cpp
Lines 430 to 434 in b4e2a24
godot/modules/gdscript/gdscript_function.h
Lines 47 to 65 in b4e2a24