From 7d0d6aa16f1c59adb94cd98f6a5d4980cfff0697 Mon Sep 17 00:00:00 2001 From: rune-scape Date: Mon, 12 Dec 2022 00:58:26 -0500 Subject: [PATCH] GDScript: Fix cast producing null --- modules/gdscript/gdscript_compiler.cpp | 29 +++++++++++-------- .../analyzer/features/cast_non_null.gd | 5 ++++ .../analyzer/features/cast_non_null.out | 3 ++ 3 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 modules/gdscript/tests/scripts/analyzer/features/cast_non_null.gd create mode 100644 modules/gdscript/tests/scripts/analyzer/features/cast_non_null.out diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index c0539c7e450f..287f88fda20b 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -490,24 +490,29 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } break; case GDScriptParser::Node::CAST: { const GDScriptParser::CastNode *cn = static_cast(p_expression); - GDScriptParser::DataType og_cast_type = cn->cast_type->get_datatype(); + GDScriptParser::DataType og_cast_type = cn->get_datatype(); GDScriptDataType cast_type = _gdtype_from_datatype(og_cast_type, codegen.script); - if (og_cast_type.kind == GDScriptParser::DataType::ENUM) { - // Enum types are usually treated as dictionaries, but in this case we want to cast to an integer. - cast_type.kind = GDScriptDataType::BUILTIN; - cast_type.builtin_type = Variant::INT; - } + GDScriptCodeGenerator::Address result; + if (cast_type.has_type) { + if (og_cast_type.kind == GDScriptParser::DataType::ENUM) { + // Enum types are usually treated as dictionaries, but in this case we want to cast to an integer. + cast_type.kind = GDScriptDataType::BUILTIN; + cast_type.builtin_type = Variant::INT; + } - // Create temporary for result first since it will be deleted last. - GDScriptCodeGenerator::Address result = codegen.add_temporary(cast_type); + // Create temporary for result first since it will be deleted last. + result = codegen.add_temporary(cast_type); - GDScriptCodeGenerator::Address src = _parse_expression(codegen, r_error, cn->operand); + GDScriptCodeGenerator::Address src = _parse_expression(codegen, r_error, cn->operand); - gen->write_cast(result, src, cast_type); + gen->write_cast(result, src, cast_type); - if (src.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + if (src.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); + } + } else { + result = _parse_expression(codegen, r_error, cn->operand); } return result; diff --git a/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.gd b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.gd new file mode 100644 index 000000000000..ba1b198cbf94 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.gd @@ -0,0 +1,5 @@ +# https://github.com/godotengine/godot/issues/69504#issuecomment-1345725988 + +func test(): + print("cast to Variant == null: ", 1 as Variant == null) + print("cast to Object == null: ", self as Object == null) diff --git a/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.out b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.out new file mode 100644 index 000000000000..541de99b8e8c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.out @@ -0,0 +1,3 @@ +GDTEST_OK +cast to Variant == null: false +cast to Object == null: false