diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index f5815a5a1..9ac1a618d 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -572,7 +572,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::listlibrary.isnoreturn(tok->str()) && tok->strAt(-1) != "=") + if ((_settings->library.isnoreturn(tok->str()) || (tok->function() && tok->function()->isAttributeNoreturn())) && tok->strAt(-1) != "=") return "exit"; if (varid > 0 && (getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No)) @@ -1277,7 +1277,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listlibrary.isnoreturn(tok->str())) + if (_settings->library.isnoreturn(tok->str()) || (tok->function() && tok->function()->isAttributeNoreturn())) addtoken(&rettail, tok, "exit"); else if (!test_white_list_with_lib(tok->str(), _settings)) { diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a48d1eba6..55efb483d 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1152,7 +1152,7 @@ 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()) && tok->strAt(-1) != ".") { + } else if (Token::Match(tok, "%var% (") && (_settings->library.isnoreturn(tok->str()) || (tok->function() && tok->function()->isAttributeNoreturn())) && tok->strAt(-1) != ".") { if ((!tok->function() || (tok->function()->token != tok && tok->function()->tokenDef != tok)) && tok->linkAt(1)->strAt(1) != "{") secondBreak = tok->linkAt(1)->tokAt(2); } diff --git a/lib/library.cpp b/lib/library.cpp index 43624b17f..b5f2f7579 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -22,6 +22,7 @@ #include "tokenlist.h" #include "mathlib.h" #include "token.h" +#include "symboldatabase.h" #include #include @@ -526,7 +527,7 @@ bool Library::isScopeNoReturn(const Token *end, std::string *unknownFunc) const if (funcname->str() == "exit") return true; if (!isnotnoreturn(funcname->str())) { - if (unknownFunc && !isnoreturn(funcname->str())) + if (unknownFunc && !(isnoreturn(funcname->str()) || (funcname->function() && funcname->function()->isAttributeNoreturn()))) *unknownFunc = funcname->str(); return true; } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1b5ef5449..28c5195d5 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4259,7 +4259,7 @@ void Tokenizer::simplifyFlowControl() } else if (Token::Match(tok,"return|goto") || (Token::Match(tok->previous(), "[;{}] %var% (") && - _settings->library.isnoreturn(tok->str())) || + (_settings->library.isnoreturn(tok->str()) || (tok->function() && tok->function()->isAttributeNoreturn()))) || (tok->str() == "throw" && !isC())) { //TODO: ensure that we exclude user-defined 'exit|abort|throw', except for 'noreturn' //catch the first ';'