value flow: some simplifications in unknown functions when there is library configuration
This commit is contained in:
parent
ab866be03a
commit
2e67ca06c0
|
@ -44,7 +44,7 @@ static void bailout(TokenList *tokenlist, ErrorLogger *errorLogger, const Token
|
||||||
errorLogger->reportErr(errmsg);
|
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?
|
// passing variable to subfunction?
|
||||||
const bool addr = tok && Token::Match(tok->previous(), "&");
|
const bool addr = tok && Token::Match(tok->previous(), "&");
|
||||||
|
@ -64,8 +64,11 @@ static bool bailoutFunctionPar(const Token *tok)
|
||||||
if (!Token::Match(tok,"%var% ("))
|
if (!Token::Match(tok,"%var% ("))
|
||||||
return false; // not a function => dont bailout
|
return false; // not a function => dont bailout
|
||||||
|
|
||||||
if (!tok->function())
|
if (!tok->function()) {
|
||||||
return true; // unknown function bailout
|
// 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);
|
const Variable *arg = tok->function()->getArgumentVar(argnr);
|
||||||
|
|
||||||
|
@ -210,7 +213,7 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
|
||||||
}
|
}
|
||||||
|
|
||||||
// assigned by subfunction?
|
// assigned by subfunction?
|
||||||
if (bailoutFunctionPar(tok2)) {
|
if (bailoutFunctionPar(tok2,val2.condition ? val2 : val,settings)) {
|
||||||
if (settings->debugwarnings)
|
if (settings->debugwarnings)
|
||||||
bailout(tokenlist, errorLogger, tok2, "possible assignment of " + tok2->str() + " by subfunction");
|
bailout(tokenlist, errorLogger, tok2, "possible assignment of " + tok2->str() + " by subfunction");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -43,6 +43,13 @@ private:
|
||||||
Settings settings;
|
Settings settings;
|
||||||
settings.valueFlow = true; // temporary flag
|
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..
|
// Tokenize..
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
std::istringstream istr(code);
|
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(std::string("void setx(int &x);")+code, 2U, 1));
|
||||||
ASSERT_EQUALS(false, testValueOfX(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
|
// while, for, do-while
|
||||||
code = "void f(int x) {\n" // loop condition, x is not assigned inside loop => use condition
|
code = "void f(int x) {\n" // loop condition, x is not assigned inside loop => use condition
|
||||||
" a = x;\n" // x can be 37
|
" a = x;\n" // x can be 37
|
||||||
|
|
Loading…
Reference in New Issue