missingReturn; Fixed false positives

This commit is contained in:
Daniel Marjamäki 2021-07-10 08:36:54 +02:00
parent 9fc5b9472d
commit c6f7a78ebb
3 changed files with 27 additions and 14 deletions

View File

@ -271,21 +271,26 @@ void CheckFunctions::checkMissingReturn()
static const Token *checkMissingReturnScope(const Token *tok)
{
tok = tok->previous();
while (tok) {
const Token *lastStatement = nullptr;
while ((tok = tok->previous()) != nullptr) {
if (tok->str() == "{")
return tok->next();
return lastStatement ? lastStatement : tok->next();
if (tok->str() == "}") {
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 (tok->scope()->type == Scope::ScopeType::eSwitch) {
// find break/default
// find reachable break / !default
bool hasDefault = false;
bool reachable = false;
for (const Token *switchToken = tok->link(); switchToken != tok; switchToken = switchToken->next()) {
if (Token::simpleMatch(switchToken, "break ;"))
if (reachable && Token::simpleMatch(switchToken, "break ;"))
return switchToken;
if (switchToken->isKeyword() && Token::Match(switchToken, "return|throw"))
reachable = false;
if (Token::Match(switchToken, "case|default"))
reachable = true;
if (Token::simpleMatch(switchToken, "default :"))
hasDefault = true;
else if (switchToken->str() == "{" && switchToken->scope()->isLoopScope())
@ -309,9 +314,8 @@ static const Token *checkMissingReturnScope(const Token *tok)
}
if (tok->isKeyword() && Token::Match(tok, "return|throw"))
return nullptr;
if (Token::Match(tok, "; !!}"))
return tok->next();
tok = tok->previous();
if (Token::Match(tok, "; !!}") && !lastStatement)
lastStatement = tok->next();
}
return nullptr;
}

View File

@ -385,12 +385,6 @@ public:
mTokType == eBoolean || mTokType == eLiteral || mTokType == eEnumerator);
setFlag(fIsLiteral, memoizedIsLiteral);
}
void isKeyword(const bool kwd) {
if (kwd)
tokType(eKeyword);
else if (mTokType == eKeyword)
tokType(eName);
}
bool isKeyword() const {
return mTokType == eKeyword;
}

View File

@ -1379,6 +1379,13 @@ private:
check("auto foo4() -> void {}");
ASSERT_EQUALS("", errout.str());
// unreachable code..
check("int foo(int x) {\n"
" return 1;\n"
" (void)x;\n"
"}");
ASSERT_EQUALS("", errout.str());
// switch
check("int f() {\n"
" switch (x) {\n"
@ -1388,6 +1395,14 @@ private:
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Found a exit path from function with non-void return type that has missing return statement\n", errout.str());
check("int f() {\n"
" switch (x) {\n"
" case 1: return 2; break;\n"
" default: return 1;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
// if/else
check("int f(int x) {\n"
" if (x) {\n"