Fixed #8208 (CheckCondition: Use Library to determine if function is const)

This commit is contained in:
Daniel Marjamäki 2017-09-08 18:08:32 +02:00
parent 7e92535b59
commit b81b4fcb78
3 changed files with 15 additions and 4 deletions

View File

@ -454,8 +454,10 @@ void CheckCondition::multiConditionError(const Token *tok, unsigned int line1)
// - same condition after early exit => always false // - same condition after early exit => always false
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static bool isNonConstFunctionCall(const Token *ftok) static bool isNonConstFunctionCall(const Token *ftok, const Library &library)
{ {
if (library.isFunctionConst(ftok))
return false;
const Token *obj = ftok->next()->astOperand1(); const Token *obj = ftok->next()->astOperand1();
while (obj && obj->str() == ".") while (obj && obj->str() == ".")
obj = obj->astOperand1(); obj = obj->astOperand1();
@ -507,7 +509,7 @@ void CheckCondition::multiCondition2()
continue; continue;
if (Token::Match(cond, "%name% (")) { if (Token::Match(cond, "%name% (")) {
nonConstFunctionCall = isNonConstFunctionCall(cond); nonConstFunctionCall = isNonConstFunctionCall(cond, _settings->library);
if (nonConstFunctionCall) if (nonConstFunctionCall)
break; break;
} }
@ -585,7 +587,7 @@ void CheckCondition::multiCondition2()
} }
} }
} }
if (Token::Match(tok, "%type% (") && nonlocal && isNonConstFunctionCall(tok)) // non const function call -> bailout if there are nonlocal variables if (Token::Match(tok, "%type% (") && nonlocal && isNonConstFunctionCall(tok, _settings->library)) // non const function call -> bailout if there are nonlocal variables
break; break;
if (Token::Match(tok, "case|break|continue|return|throw") && tok->scope() == endToken->scope()) if (Token::Match(tok, "case|break|continue|return|throw") && tok->scope() == endToken->scope())
break; break;

View File

@ -1070,7 +1070,15 @@ bool Library::isFunctionConst(const std::string& functionName, bool pure) const
return pure ? it->second.ispure : it->second.isconst; return pure ? it->second.ispure : it->second.isconst;
return false; return false;
} }
bool Library::isFunctionConst(const Token *ftok) const
{
if (ftok->function() && ftok->function()->isAttributeConst())
return true;
if (isNotLibraryFunction(ftok))
return false;
std::map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
return (it != functions.end() && it->second.isconst);
}
bool Library::isnoreturn(const Token *ftok) const bool Library::isnoreturn(const Token *ftok) const
{ {
if (ftok->function() && ftok->function()->isAttributeNoreturn()) if (ftok->function() && ftok->function()->isAttributeNoreturn())

View File

@ -280,6 +280,7 @@ public:
bool isUse(const std::string& functionName) const; bool isUse(const std::string& functionName) const;
bool isLeakIgnore(const std::string& functionName) const; bool isLeakIgnore(const std::string& functionName) const;
bool isFunctionConst(const std::string& functionName, bool pure) const; bool isFunctionConst(const std::string& functionName, bool pure) const;
bool isFunctionConst(const Token *ftok) const;
bool isboolargbad(const Token *ftok, int argnr) const { bool isboolargbad(const Token *ftok, int argnr) const {
const ArgumentChecks *arg = getarg(ftok, argnr); const ArgumentChecks *arg = getarg(ftok, argnr);