Refactoring: Move isScopeNoReturn implementation to library and reuse it both in ValueFlow and Tokenizer
This commit is contained in:
parent
c19fc08a68
commit
ae81b09b58
|
@ -376,3 +376,35 @@ const Library::ArgumentChecks * Library::getarg(const std::string &functionName,
|
|||
return &it3->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Library::isScopeNoReturn(const Token *end, std::string *unknownFunc) const
|
||||
{
|
||||
if (unknownFunc)
|
||||
unknownFunc->clear();
|
||||
|
||||
if (!Token::simpleMatch(end->tokAt(-2), ") ; }"))
|
||||
return false;
|
||||
|
||||
const Token *funcname = end->linkAt(-2)->previous();
|
||||
const Token *start = funcname;
|
||||
if (funcname && Token::Match(funcname->tokAt(-3),"( * %var% )")) {
|
||||
funcname = funcname->previous();
|
||||
start = funcname->tokAt(-3);
|
||||
} else if (funcname->isName()) {
|
||||
while (Token::Match(start, "%var%|.|::"))
|
||||
start = start->previous();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (Token::Match(start,"[;{}]") && Token::Match(funcname, "%var% )| (")) {
|
||||
if (funcname->str() == "exit")
|
||||
return true;
|
||||
if (!isnotnoreturn(funcname->str())) {
|
||||
if (unknownFunc && !isnoreturn(funcname->str()))
|
||||
*unknownFunc = funcname->str();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,8 @@ public:
|
|||
return (it != _noreturn.end() && !it->second);
|
||||
}
|
||||
|
||||
bool isScopeNoReturn(const Token *end, std::string *unknownFunc) const;
|
||||
|
||||
class ArgumentChecks {
|
||||
public:
|
||||
ArgumentChecks() :
|
||||
|
|
|
@ -7834,50 +7834,17 @@ void Tokenizer::simplifyStd()
|
|||
|
||||
bool Tokenizer::IsScopeNoReturn(const Token *endScopeToken, bool *unknown) const
|
||||
{
|
||||
std::string unknownFunc;
|
||||
bool ret = _settings->library.isScopeNoReturn(endScopeToken,&unknownFunc);
|
||||
if (unknown)
|
||||
*unknown = false;
|
||||
|
||||
if (Token::simpleMatch(endScopeToken->tokAt(-2), ") ; }")) {
|
||||
const Token *tok = endScopeToken->linkAt(-2)->previous();
|
||||
|
||||
if (!tok)
|
||||
return true;
|
||||
|
||||
// function pointer call..
|
||||
if (Token::Match(tok->tokAt(-4), "[;{}] ( * %var% )"))
|
||||
return true;
|
||||
|
||||
if (!tok->isName())
|
||||
return false;
|
||||
|
||||
if (tok->str() == "exit")
|
||||
return true;
|
||||
|
||||
while (tok && (Token::Match(tok, "::|.") || tok->isName()))
|
||||
tok = tok->previous();
|
||||
|
||||
if (Token::Match(tok, "[;{}] %var% (")) {
|
||||
if (_settings->library.isnoreturn(tok->next()->str()))
|
||||
return true;
|
||||
if (_settings->library.isnotnoreturn(tok->next()->str()))
|
||||
return false;
|
||||
|
||||
if (_settings->checkLibrary && _settings->isEnabled("information")) {
|
||||
reportError(tok->next(),
|
||||
*unknown = !unknownFunc.empty();
|
||||
if (!unknownFunc.empty() && _settings->checkLibrary && _settings->isEnabled("information")) {
|
||||
reportError(endScopeToken->previous(),
|
||||
Severity::information,
|
||||
"checkLibraryNoReturn",
|
||||
"--check-library: Function " + tok->next()->str() + "() should have <noreturn> configuration");
|
||||
"--check-library: Function " + unknownFunc + "() should have <noreturn> configuration");
|
||||
}
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "[;{}]")) {
|
||||
if (unknown)
|
||||
*unknown = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -867,24 +867,12 @@ static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogg
|
|||
// After conditional code..
|
||||
if (ok && !scopeEnd.empty() && Token::simpleMatch(top->link(), ") {")) {
|
||||
Token *after = top->link()->linkAt(1);
|
||||
if (Token::simpleMatch(after->tokAt(-2), ") ; }")) {
|
||||
const Token *funcname = after->linkAt(-2)->previous();
|
||||
const Token *start = funcname;
|
||||
if (funcname && Token::Match(funcname->tokAt(-3),"( * %var% )")) {
|
||||
funcname = funcname->previous();
|
||||
start = funcname->tokAt(-3);
|
||||
} else {
|
||||
while (Token::Match(start, "%var%|.|::"))
|
||||
start = start->previous();
|
||||
}
|
||||
if (Token::Match(start,"[;{}]") && Token::Match(funcname, "%var% )| (")) {
|
||||
if (!settings->library.isnotnoreturn(funcname->str())) {
|
||||
if (settings->debugwarnings)
|
||||
std::string unknownFunction;
|
||||
if (settings->library.isScopeNoReturn(after,&unknownFunction)) {
|
||||
if (settings->debugwarnings && !unknownFunction.empty())
|
||||
bailout(tokenlist, errorLogger, after, "possible noreturn scope");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Token::simpleMatch(after, "} else {")) {
|
||||
after = after->linkAt(2);
|
||||
if (Token::simpleMatch(after->tokAt(-2), ") ; }")) {
|
||||
|
|
Loading…
Reference in New Issue