missingReturn; Fixed false positives
This commit is contained in:
parent
9fc5b9472d
commit
c6f7a78ebb
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue