value flow: some simplifications in unknown functions when there is library configuration

This commit is contained in:
Daniel Marjamäki 2014-01-12 18:19:00 +01:00
parent ab866be03a
commit 2e67ca06c0
2 changed files with 20 additions and 4 deletions

View File

@ -44,7 +44,7 @@ static void bailout(TokenList *tokenlist, ErrorLogger *errorLogger, const Token
errorLogger->reportErr(errmsg);
}
static bool bailoutFunctionPar(const Token *tok)
static bool bailoutFunctionPar(const Token *tok, const ValueFlow::Value &value, const Settings *settings)
{
// passing variable to subfunction?
const bool addr = tok && Token::Match(tok->previous(), "&");
@ -64,8 +64,11 @@ static bool bailoutFunctionPar(const Token *tok)
if (!Token::Match(tok,"%var% ("))
return false; // not a function => dont bailout
if (!tok->function())
return true; // unknown function bailout
if (!tok->function()) {
// unknown function.. bailout unless value is 0 and the library
// says 0 is invalid
return (value.intvalue!=0 || !settings->library.isnullargbad(tok->str(), 1+argnr));
}
const Variable *arg = tok->function()->getArgumentVar(argnr);
@ -210,7 +213,7 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
}
// assigned by subfunction?
if (bailoutFunctionPar(tok2)) {
if (bailoutFunctionPar(tok2,val2.condition ? val2 : val,settings)) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "possible assignment of " + tok2->str() + " by subfunction");
break;

View File

@ -43,6 +43,13 @@ private:
Settings settings;
settings.valueFlow = true; // temporary flag
// strcpy cfg
const char cfg[] = "<?xml version=\"1.0\"?>\n"
"<def>\n"
" <function name=\"strcpy\"> <arg nr=\"1\"><not-null/></arg> </function>\n"
"</def>";
settings.library.loadxmldata(cfg, sizeof(cfg));
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
@ -143,6 +150,12 @@ private:
ASSERT_EQUALS(false, testValueOfX(std::string("void setx(int &x);")+code, 2U, 1));
ASSERT_EQUALS(false, testValueOfX(code, 2U, 1));
code = "void f(char* x) {\n"
" strcpy(x,\"abc\");\n"
" if (x) {}\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 2U, 0));
// while, for, do-while
code = "void f(int x) {\n" // loop condition, x is not assigned inside loop => use condition
" a = x;\n" // x can be 37