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)
|
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% :"))
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue