diff --git a/src/checkother.cpp b/src/checkother.cpp index 47a8a73ff..7e1fef77b 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -802,29 +802,27 @@ void CheckOther::CheckIncompleteStatement() void CheckOther::unreachableCode() { - const Token *tok = Token::findmatch(_tokenizer->tokens(), "[;{}] return"); - while (tok) + const Token *tok = _tokenizer->tokens(); + while ((tok = Token::findmatch(tok, "[;{}] return"))) { // Goto the 'return' token tok = tok->next(); // Locate the end of the 'return' statement - while (tok && ! Token::Match(tok, ";")) + while (tok && tok->str() != ";") tok = tok->next(); - while (tok && Token::Match(tok->next(), ";")) + while (tok && tok->next() && tok->next()->str() == ";") tok = tok->next(); if (!tok) break; // If there is a statement below the return it is unreachable - if (!Token::Match(tok, "; case|default|}|#") && !Token::Match(tok, "; %var% :")) + if ( !Token::Match(tok, "; case|default|}|#") && !Token::Match(tok, "; %var% :") + && ( _settings._checkCodingStyle || !Token::simpleMatch(tok, "; break") ) ) { _errorLogger->reportErr(ErrorMessage::unreachableCode(_tokenizer, tok->next())); } - - // Find the next 'return' statement - tok = Token::findmatch(tok, "[;{}] return"); } } //--------------------------------------------------------------------------- diff --git a/test/testother.cpp b/test/testother.cpp index 9d598b1ec..e71d778d7 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -37,6 +37,8 @@ private: TEST_CASE(delete1); TEST_CASE(delete2); + TEST_CASE(unreachable1); + TEST_CASE(sprintf1); // Dangerous usage of sprintf TEST_CASE(sprintf2); TEST_CASE(sprintf3); @@ -94,6 +96,20 @@ private: ASSERT_EQUALS(std::string("[test.cpp:3]: Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str()); } + void unreachable1() + { + check("void foo()\n" + "{\n" + " switch (p)\n" + " {\n" + " default:\n" + " return 0;\n" + " break;\n" + " }\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); + } + void sprintfUsage(const char code[])