Skip to content

Commit c6f7a78

Browse files
committed
missingReturn; Fixed false positives
1 parent 9fc5b94 commit c6f7a78

3 files changed

Lines changed: 27 additions & 14 deletions

File tree

lib/checkfunctions.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,21 +271,26 @@ void CheckFunctions::checkMissingReturn()
271271

272272
static const Token *checkMissingReturnScope(const Token *tok)
273273
{
274-
tok = tok->previous();
275-
while (tok) {
274+
const Token *lastStatement = nullptr;
275+
while ((tok = tok->previous()) != nullptr) {
276276
if (tok->str() == "{")
277-
return tok->next();
277+
return lastStatement ? lastStatement : tok->next();
278278
if (tok->str() == "}") {
279279
for (const Token *prev = tok->link()->previous(); prev && prev->scope() == tok->scope() && !Token::Match(prev, "[;{}]"); prev = prev->previous()) {
280280
if (prev->isKeyword() && Token::Match(prev, "return|throw"))
281281
return nullptr;
282282
}
283283
if (tok->scope()->type == Scope::ScopeType::eSwitch) {
284-
// find break/default
284+
// find reachable break / !default
285285
bool hasDefault = false;
286+
bool reachable = false;
286287
for (const Token *switchToken = tok->link(); switchToken != tok; switchToken = switchToken->next()) {
287-
if (Token::simpleMatch(switchToken, "break ;"))
288+
if (reachable && Token::simpleMatch(switchToken, "break ;"))
288289
return switchToken;
290+
if (switchToken->isKeyword() && Token::Match(switchToken, "return|throw"))
291+
reachable = false;
292+
if (Token::Match(switchToken, "case|default"))
293+
reachable = true;
289294
if (Token::simpleMatch(switchToken, "default :"))
290295
hasDefault = true;
291296
else if (switchToken->str() == "{" && switchToken->scope()->isLoopScope())
@@ -309,9 +314,8 @@ static const Token *checkMissingReturnScope(const Token *tok)
309314
}
310315
if (tok->isKeyword() && Token::Match(tok, "return|throw"))
311316
return nullptr;
312-
if (Token::Match(tok, "; !!}"))
313-
return tok->next();
314-
tok = tok->previous();
317+
if (Token::Match(tok, "; !!}") && !lastStatement)
318+
lastStatement = tok->next();
315319
}
316320
return nullptr;
317321
}

lib/token.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,6 @@ class CPPCHECKLIB Token {
385385
mTokType == eBoolean || mTokType == eLiteral || mTokType == eEnumerator);
386386
setFlag(fIsLiteral, memoizedIsLiteral);
387387
}
388-
void isKeyword(const bool kwd) {
389-
if (kwd)
390-
tokType(eKeyword);
391-
else if (mTokType == eKeyword)
392-
tokType(eName);
393-
}
394388
bool isKeyword() const {
395389
return mTokType == eKeyword;
396390
}

test/testfunctions.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,13 @@ class TestFunctions : public TestFixture {
13791379
check("auto foo4() -> void {}");
13801380
ASSERT_EQUALS("", errout.str());
13811381

1382+
// unreachable code..
1383+
check("int foo(int x) {\n"
1384+
" return 1;\n"
1385+
" (void)x;\n"
1386+
"}");
1387+
ASSERT_EQUALS("", errout.str());
1388+
13821389
// switch
13831390
check("int f() {\n"
13841391
" switch (x) {\n"
@@ -1388,6 +1395,14 @@ class TestFunctions : public TestFixture {
13881395
"}");
13891396
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());
13901397

1398+
check("int f() {\n"
1399+
" switch (x) {\n"
1400+
" case 1: return 2; break;\n"
1401+
" default: return 1;\n"
1402+
" }\n"
1403+
"}");
1404+
ASSERT_EQUALS("", errout.str());
1405+
13911406
// if/else
13921407
check("int f(int x) {\n"
13931408
" if (x) {\n"

0 commit comments

Comments
 (0)