From 5e3ccda408ed2b78eb7dbf113a88246d8e32db9f Mon Sep 17 00:00:00 2001 From: PKEuS Date: Tue, 6 Aug 2013 02:11:59 -0700 Subject: [PATCH] Added support for noreturn functions from library to CheckOther::checkUnreachableCode() --- lib/checkother.cpp | 2 ++ lib/library.h | 5 +++++ test/testother.cpp | 37 ++++++++++++++++++++++++------------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index ff49aeea3..d68a0fee0 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1567,6 +1567,8 @@ void CheckOther::checkUnreachableCode() } else if (Token::Match(tok, "goto %any% ;")) { secondBreak = tok->tokAt(3); labelName = tok->next(); + } else if (Token::Match(tok, "%var% (") && _settings->library.isnoreturn(tok->str())) { + secondBreak = tok->linkAt(1)->tokAt(2); } // Statements follow directly, no line between them. (#3383) diff --git a/lib/library.h b/lib/library.h index 09c7a814c..b822c5d25 100644 --- a/lib/library.h +++ b/lib/library.h @@ -57,6 +57,11 @@ public: _dealloc[functionname] = id; } + /** add noreturn function setting */ + void setnoreturn(const std::string& funcname, bool noreturn) { + _noreturn[funcname] = noreturn; + } + /** is allocation type memory? */ static bool ismemory(int id) { return ((id > 0) && ((id & 1) == 0)); diff --git a/test/testother.cpp b/test/testother.cpp index f0bc397c5..792a47742 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -178,27 +178,30 @@ private: TEST_CASE(checkCommaSeparatedReturn); } - void check(const char code[], const char *filename = NULL, bool experimental = false, bool inconclusive = true, bool posix = false, bool runSimpleChecks=true) { + void check(const char code[], const char *filename = NULL, bool experimental = false, bool inconclusive = true, bool posix = false, bool runSimpleChecks=true, Settings* settings = 0) { // Clear the error buffer.. errout.str(""); - Settings settings; - settings.addEnabled("style"); - settings.addEnabled("warning"); - settings.addEnabled("portability"); - settings.addEnabled("performance"); - settings.inconclusive = inconclusive; - settings.experimental = experimental; - settings.standards.posix = posix; + if (!settings) { + static Settings _settings; + settings = &_settings; + } + settings->addEnabled("style"); + settings->addEnabled("warning"); + settings->addEnabled("portability"); + settings->addEnabled("performance"); + settings->inconclusive = inconclusive; + settings->experimental = experimental; + settings->standards.posix = posix; // Tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(settings, this); std::istringstream istr(code); tokenizer.tokenize(istr, filename ? filename : "test.cpp"); // Check.. - CheckOther checkOther(&tokenizer, &settings, this); - checkOther.runChecks(&tokenizer, &settings, this); + CheckOther checkOther(&tokenizer, settings, this); + checkOther.runChecks(&tokenizer, settings, this); if (runSimpleChecks) { const std::string str1(tokenizer.tokens()->stringifyList(0,true)); @@ -206,7 +209,7 @@ private: const std::string str2(tokenizer.tokens()->stringifyList(0,true)); if (str1 != str2) warn(("Unsimplified code in test case\nstr1="+str1+"\nstr2="+str2).c_str()); - checkOther.runSimplifiedChecks(&tokenizer, &settings, this); + checkOther.runSimplifiedChecks(&tokenizer, settings, this); } } @@ -2658,6 +2661,14 @@ private: "}", 0, false, false, false, false); ASSERT_EQUALS("[test.cpp:3]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.\n", errout.str()); + Settings settings; + settings.library.setnoreturn("exit", true); + check("void foo() {\n" + " exit(0);\n" + " break;\n" + "}", 0, false, false, false, false, &settings); + ASSERT_EQUALS("[test.cpp:3]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.\n", errout.str()); + check("void foo(int a)\n" "{\n" " switch(a) {\n"