missing return; False positive when goto jumps back
This commit is contained in:
parent
e4ae4471e8
commit
a336c07663
|
@ -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)
|
||||
{
|
||||
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()) {
|
||||
if (prev->isKeyword() && Token::Match(prev, "return|throw"))
|
||||
return nullptr;
|
||||
if (prev->str() == "goto" && !isForwardJump(prev))
|
||||
return nullptr;
|
||||
}
|
||||
if (tok->scope()->type == Scope::ScopeType::eSwitch) {
|
||||
// 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"))
|
||||
return nullptr;
|
||||
if (tok->str() == "goto" && !isForwardJump(tok))
|
||||
return nullptr;
|
||||
if (Token::Match(tok, "%name% (") && library.isnoreturn(tok))
|
||||
return nullptr;
|
||||
if (Token::Match(tok, "[;{}] %name% :"))
|
||||
|
|
|
@ -1379,6 +1379,15 @@ private:
|
|||
check("auto foo4() -> void {}");
|
||||
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..
|
||||
check("int foo(int x) {\n"
|
||||
" return 1;\n"
|
||||
|
|
Loading…
Reference in New Issue