missingReturn; Improved handling of noreturn function

This commit is contained in:
Daniel Marjamäki 2021-07-10 08:59:01 +02:00
parent 53955b48d2
commit a8fb0309fd
2 changed files with 13 additions and 5 deletions

View File

@ -248,7 +248,7 @@ void CheckFunctions::ignoredReturnErrorCode(const Token* tok, const std::string&
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Check for ignored return values. // Check for ignored return values.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static const Token *checkMissingReturnScope(const Token *tok); static const Token *checkMissingReturnScope(const Token *tok, const Library &library);
void CheckFunctions::checkMissingReturn() void CheckFunctions::checkMissingReturn()
{ {
@ -263,13 +263,13 @@ void CheckFunctions::checkMissingReturn()
continue; continue;
if (Function::returnsVoid(function, true)) if (Function::returnsVoid(function, true))
continue; continue;
const Token *errorToken = checkMissingReturnScope(scope->bodyEnd); const Token *errorToken = checkMissingReturnScope(scope->bodyEnd, mSettings->library);
if (errorToken) if (errorToken)
missingReturnError(errorToken); missingReturnError(errorToken);
} }
} }
static const Token *checkMissingReturnScope(const Token *tok) static const Token *checkMissingReturnScope(const Token *tok, const Library &library)
{ {
const Token *lastStatement = nullptr; const Token *lastStatement = nullptr;
while ((tok = tok->previous()) != nullptr) { while ((tok = tok->previous()) != nullptr) {
@ -289,6 +289,8 @@ static const Token *checkMissingReturnScope(const Token *tok)
return switchToken; return switchToken;
if (switchToken->isKeyword() && Token::Match(switchToken, "return|throw")) if (switchToken->isKeyword() && Token::Match(switchToken, "return|throw"))
reachable = false; reachable = false;
if (Token::Match(switchToken, "%name% (") && library.isnoreturn(switchToken))
reachable = false;
if (Token::Match(switchToken, "case|default")) if (Token::Match(switchToken, "case|default"))
reachable = true; reachable = true;
if (Token::simpleMatch(switchToken, "default :")) if (Token::simpleMatch(switchToken, "default :"))
@ -301,12 +303,12 @@ static const Token *checkMissingReturnScope(const Token *tok)
} else if (tok->scope()->type == Scope::ScopeType::eIf) { } else if (tok->scope()->type == Scope::ScopeType::eIf) {
return tok; return tok;
} else if (tok->scope()->type == Scope::ScopeType::eElse) { } else if (tok->scope()->type == Scope::ScopeType::eElse) {
const Token *errorToken = checkMissingReturnScope(tok); const Token *errorToken = checkMissingReturnScope(tok, library);
if (errorToken) if (errorToken)
return errorToken; return errorToken;
tok = tok->link(); tok = tok->link();
if (Token::simpleMatch(tok->tokAt(-2), "} else {")) if (Token::simpleMatch(tok->tokAt(-2), "} else {"))
return checkMissingReturnScope(tok->tokAt(-2)); return checkMissingReturnScope(tok->tokAt(-2), library);
return tok; return tok;
} }
// FIXME // FIXME
@ -314,6 +316,8 @@ static const Token *checkMissingReturnScope(const Token *tok)
} }
if (tok->isKeyword() && Token::Match(tok, "return|throw")) if (tok->isKeyword() && Token::Match(tok, "return|throw"))
return nullptr; return nullptr;
if (Token::Match(tok, "%name% (") && library.isnoreturn(tok))
return nullptr;
if (Token::Match(tok, "[;{}] %name% :")) if (Token::Match(tok, "[;{}] %name% :"))
return tok; return tok;
if (Token::Match(tok, "; !!}") && !lastStatement) if (Token::Match(tok, "; !!}") && !lastStatement)

View File

@ -1443,6 +1443,10 @@ private:
" return {1, 2};\n" " return {1, 2};\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// noreturn function
check("int f(int x) { exit(0); }");
ASSERT_EQUALS("", errout.str());
} }
// NRVO check // NRVO check
void returnLocalStdMove1() { void returnLocalStdMove1() {