summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
authorShiqing <shiqing-thu18@yandex.com>2019-07-13 10:15:27 +0800
committerShiqing <shiqing-thu18@yandex.com>2019-07-13 19:31:49 +0800
commit206d515783814377381d95d5b0893d6fd308e5eb (patch)
tree9a73cd8caa18ec99435691f93596e145bc4051c4 /modules/gdscript
parent584ca0f156cec64c259382895e105cf27566a987 (diff)
Fix unreachable code detection in match statements
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/gdscript_parser.cpp21
1 files changed, 19 insertions, 2 deletions
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 80da606967..fa430b5364 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -2211,6 +2211,8 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
p_block->has_return = true;
+ bool catch_all_appeared = false;
+
while (true) {
while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline())
@@ -2221,7 +2223,7 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
return;
if (indent_level > tab_level.back()->get()) {
- return; // go back a level
+ break; // go back a level
}
if (pending_newline != -1) {
@@ -2236,12 +2238,20 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
branch->patterns.push_back(_parse_pattern(p_static));
if (!branch->patterns[0]) {
- return;
+ break;
}
bool has_binding = branch->patterns[0]->pt_type == PatternNode::PT_BIND;
bool catch_all = has_binding || branch->patterns[0]->pt_type == PatternNode::PT_WILDCARD;
+#ifdef DEBUG_ENABLED
+ // Branches after a wildcard or binding are unreachable
+ if (catch_all_appeared && !current_function->has_unreachable_code) {
+ _add_warning(GDScriptWarning::UNREACHABLE_CODE, -1, current_function->name.operator String());
+ current_function->has_unreachable_code = true;
+ }
+#endif
+
while (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
tokenizer->advance();
branch->patterns.push_back(_parse_pattern(p_static));
@@ -2259,6 +2269,8 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
catch_all = catch_all || pt == PatternNode::PT_WILDCARD;
}
+ catch_all_appeared = catch_all_appeared || catch_all;
+
if (!_enter_indent_block()) {
_set_error("Expected block in pattern branch");
return;
@@ -2274,6 +2286,11 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
p_branches.push_back(branch);
}
+
+ // Even if all branches return, there is possibility of default fallthrough
+ if (!catch_all_appeared) {
+ p_block->has_return = false;
+ }
}
void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) {