diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 27aaaf8a4..6d10abcc0 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -825,7 +825,7 @@ void CheckOther::checkUnreachableCode() secondBreak = silencedWarning; if (!labelInFollowingLoop && !silencedCompilerWarningOnly) - unreachableCodeError(secondBreak, inconclusive); + unreachableCodeError(secondBreak, tok, inconclusive); tok = Token::findmatch(secondBreak, "[}:]"); } else if (secondBreak->scope() && secondBreak->scope()->isLoopScope() && secondBreak->str() == "}" && tok->str() == "continue") { redundantContinueError(tok); @@ -849,10 +849,18 @@ void CheckOther::duplicateBreakError(const Token *tok, bool inconclusive) "The second statement can never be executed, and so should be removed.", CWE561, inconclusive ? Certainty::inconclusive : Certainty::normal); } -void CheckOther::unreachableCodeError(const Token *tok, bool inconclusive) +void CheckOther::unreachableCodeError(const Token *tok, const Token* noreturn, bool inconclusive) { + std::string msg = "Statements following "; + if (noreturn && noreturn->function()) + msg += "noreturn function '" + noreturn->str() + "()'"; + else if (noreturn && noreturn->isKeyword()) + msg += "'" + noreturn->str() + "'"; + else + msg += "return, break, continue, goto or throw"; + msg += " will never be executed."; reportError(tok, Severity::style, "unreachableCode", - "Statements following return, break, continue, goto or throw will never be executed.", CWE561, inconclusive ? Certainty::inconclusive : Certainty::normal); + msg, CWE561, inconclusive ? Certainty::inconclusive : Certainty::normal); } void CheckOther::redundantContinueError(const Token *tok) diff --git a/lib/checkother.h b/lib/checkother.h index f2499f31e..b95f36c8b 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -259,7 +259,7 @@ private: void duplicateValueTernaryError(const Token *tok); void duplicateExpressionTernaryError(const Token *tok, ErrorPath errors); void duplicateBreakError(const Token *tok, bool inconclusive); - void unreachableCodeError(const Token* tok, bool inconclusive); + void unreachableCodeError(const Token* tok, const Token* noreturn, bool inconclusive); void redundantContinueError(const Token* tok); void unsignedLessThanZeroError(const Token *tok, const ValueFlow::Value *v, const std::string &varname); void pointerLessThanZeroError(const Token *tok, const ValueFlow::Value *v); @@ -327,7 +327,7 @@ private: c.duplicateValueTernaryError(nullptr); c.duplicateExpressionTernaryError(nullptr, errorPath); c.duplicateBreakError(nullptr, false); - c.unreachableCodeError(nullptr, false); + c.unreachableCodeError(nullptr, nullptr, false); c.unsignedLessThanZeroError(nullptr, nullptr, "varname"); c.unsignedPositiveError(nullptr, nullptr, "varname"); c.pointerLessThanZeroError(nullptr, nullptr); diff --git a/test/testother.cpp b/test/testother.cpp index b5aec968f..83fb7557b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4291,7 +4291,7 @@ private: " return 0;\n" " foo();\n" "}", nullptr, false, false, false); - ASSERT_EQUALS("[test.cpp:3]: (style) Statements following return, break, continue, goto or throw will never be executed.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (style) Statements following 'return' will never be executed.\n", errout.str()); check("int foo(int unused) {\n" " return 0;\n" @@ -4312,7 +4312,7 @@ private: " (void)unused2;\n" " foo();\n" "}", nullptr, false, false, false); - ASSERT_EQUALS("[test.cpp:5]: (style) Statements following return, break, continue, goto or throw will never be executed.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (style) Statements following 'return' will never be executed.\n", errout.str()); check("int foo() {\n" " if(bar)\n" @@ -4349,7 +4349,7 @@ private: " return 0;\n" " j=2;\n" "}", nullptr, false, false, false); - ASSERT_EQUALS("[test.cpp:7]: (style) Statements following return, break, continue, goto or throw will never be executed.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:7]: (style) Statements following 'return' will never be executed.\n", errout.str()); check("int foo() {\n" " return 0;\n" @@ -4496,6 +4496,13 @@ private: " return INB(port_1);\n" "}\n", "test.c"); ASSERT_EQUALS("", errout.str()); + + check("[[noreturn]] void n();\n" + "void f() {\n" + " n();\n" + " g();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (style) Statements following noreturn function 'n()' will never be executed.\n", errout.str()); } void redundantContinue() {