Fix unreachable code detection in match statements
This commit is contained in:
parent
584ca0f156
commit
206d515783
@ -2211,6 +2211,8 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
|
|||||||
|
|
||||||
p_block->has_return = true;
|
p_block->has_return = true;
|
||||||
|
|
||||||
|
bool catch_all_appeared = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline())
|
while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline())
|
||||||
@ -2221,7 +2223,7 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (indent_level > tab_level.back()->get()) {
|
if (indent_level > tab_level.back()->get()) {
|
||||||
return; // go back a level
|
break; // go back a level
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending_newline != -1) {
|
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));
|
branch->patterns.push_back(_parse_pattern(p_static));
|
||||||
if (!branch->patterns[0]) {
|
if (!branch->patterns[0]) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_binding = branch->patterns[0]->pt_type == PatternNode::PT_BIND;
|
bool has_binding = branch->patterns[0]->pt_type == PatternNode::PT_BIND;
|
||||||
bool catch_all = has_binding || branch->patterns[0]->pt_type == PatternNode::PT_WILDCARD;
|
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) {
|
while (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
|
||||||
tokenizer->advance();
|
tokenizer->advance();
|
||||||
branch->patterns.push_back(_parse_pattern(p_static));
|
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 = catch_all || pt == PatternNode::PT_WILDCARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch_all_appeared = catch_all_appeared || catch_all;
|
||||||
|
|
||||||
if (!_enter_indent_block()) {
|
if (!_enter_indent_block()) {
|
||||||
_set_error("Expected block in pattern branch");
|
_set_error("Expected block in pattern branch");
|
||||||
return;
|
return;
|
||||||
@ -2274,6 +2286,11 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
|
|||||||
|
|
||||||
p_branches.push_back(branch);
|
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) {
|
void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) {
|
||||||
|
Loading…
Reference in New Issue
Block a user