diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2019-07-15 08:13:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-15 08:13:57 +0200 |
commit | 75f2575f28b2f7f40fdf213eeaebc80871218f35 (patch) | |
tree | 31e826b7f1e29810b5cb263c63b4f7fbb0027323 | |
parent | 71cd4fa40dd339c35ce3372a18709adc00b34305 (diff) | |
parent | 206d515783814377381d95d5b0893d6fd308e5eb (diff) |
Merge pull request #30552 from kawa-yoiko/match-unreachable
Fix unreachable code detection in match statements
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 21 |
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) { |