missing return; False positive when goto jumps back

This commit is contained in:
Daniel Marjamäki 2021-07-12 15:31:21 +02:00
parent e4ae4471e8
commit a336c07663
2 changed files with 26 additions and 0 deletions

View File

@ -269,6 +269,19 @@ void CheckFunctions::checkMissingReturn()
} }
} }
static bool isForwardJump(const Token *gotoToken)
{
if (!Token::Match(gotoToken, "goto %name% ;"))
return false;
for (const Token *prev = gotoToken; gotoToken; gotoToken = gotoToken->previous()) {
if (Token::Match(prev, "%name% :") && prev->str() == gotoToken->next()->str())
return true;
if (prev->str() == "{" && prev->scope()->type == Scope::eFunction)
return false;
}
return false;
}
static const Token *checkMissingReturnScope(const Token *tok, const Library &library) static const Token *checkMissingReturnScope(const Token *tok, const Library &library)
{ {
const Token *lastStatement = nullptr; const Token *lastStatement = nullptr;
@ -279,6 +292,8 @@ static const Token *checkMissingReturnScope(const Token *tok, const Library &lib
for (const Token *prev = tok->link()->previous(); prev && prev->scope() == tok->scope() && !Token::Match(prev, "[;{}]"); prev = prev->previous()) { for (const Token *prev = tok->link()->previous(); prev && prev->scope() == tok->scope() && !Token::Match(prev, "[;{}]"); prev = prev->previous()) {
if (prev->isKeyword() && Token::Match(prev, "return|throw")) if (prev->isKeyword() && Token::Match(prev, "return|throw"))
return nullptr; return nullptr;
if (prev->str() == "goto" && !isForwardJump(prev))
return nullptr;
} }
if (tok->scope()->type == Scope::ScopeType::eSwitch) { if (tok->scope()->type == Scope::ScopeType::eSwitch) {
// find reachable break / !default // find reachable break / !default
@ -316,6 +331,8 @@ static const Token *checkMissingReturnScope(const Token *tok, const Library &lib
} }
if (tok->isKeyword() && Token::Match(tok, "return|throw")) if (tok->isKeyword() && Token::Match(tok, "return|throw"))
return nullptr; return nullptr;
if (tok->str() == "goto" && !isForwardJump(tok))
return nullptr;
if (Token::Match(tok, "%name% (") && library.isnoreturn(tok)) if (Token::Match(tok, "%name% (") && library.isnoreturn(tok))
return nullptr; return nullptr;
if (Token::Match(tok, "[;{}] %name% :")) if (Token::Match(tok, "[;{}] %name% :"))

View File

@ -1379,6 +1379,15 @@ private:
check("auto foo4() -> void {}"); check("auto foo4() -> void {}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int f() {\n"
"back:\n"
" return 0;\n"
"ng:\n"
" x=y;\n"
" goto back;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
// unreachable code.. // unreachable code..
check("int foo(int x) {\n" check("int foo(int x) {\n"
" return 1;\n" " return 1;\n"