summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuri Rubinsky <chaosus89@gmail.com>2022-11-28 19:29:02 +0300
committerYuri Rubinsky <chaosus89@gmail.com>2022-11-28 19:45:24 +0300
commit8d2506e811148d6e716ec31886357a23e53dd42b (patch)
treef08635689456f9c5937c329a4abe73168565f52d
parentef090ee6eac429e51b26ea31e7882cc8cdfa2093 (diff)
Reset unassigned local variables to null in the loops
-rw-r--r--modules/gdscript/gdscript_compiler.cpp9
-rw-r--r--modules/gdscript/gdscript_parser.cpp3
-rw-r--r--modules/gdscript/gdscript_parser.h2
3 files changed, 12 insertions, 2 deletions
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 103eb60da9..24241b712b 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1875,6 +1875,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
GDScriptCodeGenerator::Address local = codegen.locals[lv->identifier->name];
GDScriptDataType local_type = _gdtype_from_datatype(lv->get_datatype(), codegen.script);
+ bool initialized = false;
if (lv->initializer != nullptr) {
// For typed arrays we need to make sure this is already initialized correctly so typed assignment work.
if (local_type.has_type && local_type.builtin_type == Variant::ARRAY) {
@@ -1896,15 +1897,23 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
codegen.generator->pop_temporary();
}
+ initialized = true;
} else if (local_type.has_type) {
// Initialize with default for type.
if (local_type.has_container_element_type()) {
codegen.generator->write_construct_typed_array(local, local_type.get_container_element_type(), Vector<GDScriptCodeGenerator::Address>());
+ initialized = true;
} else if (local_type.kind == GDScriptDataType::BUILTIN) {
codegen.generator->write_construct(local, local_type.builtin_type, Vector<GDScriptCodeGenerator::Address>());
+ initialized = true;
}
// The `else` branch is for objects, in such case we leave it as `null`.
}
+
+ // Assigns a null for the unassigned variables in loops.
+ if (!initialized && p_block->is_loop) {
+ codegen.generator->write_construct(local, Variant::NIL, Vector<GDScriptCodeGenerator::Address>());
+ }
} break;
case GDScriptParser::Node::CONSTANT: {
// Local constants.
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 24dd94873b..7f6aa5ec87 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -1835,9 +1835,9 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
}
suite->add_local(SuiteNode::Local(n_for->variable, current_function));
}
- suite->parent_for = n_for;
n_for->loop = parse_suite(R"("for" block)", suite);
+ n_for->loop->is_loop = true;
complete_extents(n_for);
// Reset break/continue state.
@@ -2169,6 +2169,7 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
is_continue_match = false;
n_while->loop = parse_suite(R"("while" block)");
+ n_while->loop->is_loop = true;
complete_extents(n_while);
// Reset break/continue state.
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index f9a1c5a697..d092a2a5e9 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -1055,12 +1055,12 @@ public:
HashMap<StringName, int> locals_indices;
FunctionNode *parent_function = nullptr;
- ForNode *parent_for = nullptr;
IfNode *parent_if = nullptr;
bool has_return = false;
bool has_continue = false;
bool has_unreachable_code = false; // Just so warnings aren't given more than once per block.
+ bool is_loop = false;
bool has_local(const StringName &p_name) const;
const Local &get_local(const StringName &p_name) const;