Skip to content

Commit

Permalink
Fix #13491 FP unreachableCode for declaration in switch (#7194)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Jan 9, 2025
1 parent ed38aee commit a219774
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
26 changes: 25 additions & 1 deletion lib/checkother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,30 @@ void CheckOther::suspiciousCaseInSwitchError(const Token* tok, const std::string
"Using an operator like '" + operatorString + "' in a case label is suspicious. Did you intend to use a bitwise operator, multiple case labels or if/else instead?", CWE398, Certainty::inconclusive);
}

static bool isNestedInSwitch(const Scope* scope)
{
while (scope) {
if (scope->type == Scope::ScopeType::eSwitch)
return true;
if (scope->type == Scope::ScopeType::eUnconditional) {
scope = scope->nestedIn;
continue;
}
break;
}
return false;
}

static bool isVardeclInSwitch(const Token* tok)
{
if (!tok)
return false;
if (!isNestedInSwitch(tok->scope()))
return false;
const Token* end = Token::findsimplematch(tok, ";");
return end && end->previous()->variable() && end->previous()->variable()->nameToken() == end->previous();
}

//---------------------------------------------------------------------------
// Find consecutive return, break, continue, goto or throw statements. e.g.:
// break; break;
Expand Down Expand Up @@ -958,7 +982,7 @@ void CheckOther::checkUnreachableCode()
if (silencedWarning)
secondBreak = silencedWarning;

if (!labelInFollowingLoop && !silencedCompilerWarningOnly)
if (!labelInFollowingLoop && !silencedCompilerWarningOnly && !isVardeclInSwitch(secondBreak))
unreachableCodeError(secondBreak, tok, inconclusive);
tok = Token::findmatch(secondBreak, "[}:]");
} else if (secondBreak->scope() && secondBreak->scope()->isLoopScope() && secondBreak->str() == "}" && tok->str() == "continue") {
Expand Down
47 changes: 47 additions & 0 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5677,6 +5677,53 @@ class TestOther : public TestFixture {
ASSERT_EQUALS("[test.cpp:6]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.\n"
"[test.cpp:1]: (style) Parameter 'argv' can be declared as const array\n",
errout_str());

check("int f(int i) {\n" // #13491
" switch (i) {\n"
" case 0:\n"
" return 0;\n"
" int j;\n"
" case 1:\n"
" case 2:\n"
" j = 5;\n"
" return j + i;\n"
" }\n"
" return 3;\n"
"}\n");
ASSERT_EQUALS("", errout_str());

check("int f(int i) {\n"
" switch (i) {\n"
" {\n"
" case 0:\n"
" return 0;\n"
" }\n"
" {\n"
" int j;\n"
" case 1:\n"
" case 2:\n"
" j = 5;\n"
" return j + i;\n"
" }\n"
" }\n"
" return 3;\n"
"}\n");
ASSERT_EQUALS("", errout_str());

check("int f(int i) {\n"
" switch (i) {\n"
" case 0:\n"
" return 0;\n"
" int j;\n"
" dostuff();\n"
" case 1:\n"
" case 2:\n"
" j = 5;\n"
" return j + i;\n"
" }\n"
" return 3;\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:6]: (style) Statements following 'return' will never be executed.\n", "", errout_str());
}

void redundantContinue() {
Expand Down

0 comments on commit a219774

Please sign in to comment.