diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7bbb3c2f7..2431e9fb1 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 076b3016a..787e9c642 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -43,6 +43,13 @@ private: Settings settings; settings.valueFlow = true; // temporary flag + // strcpy cfg + const char cfg[] = "\n" + "\n" + " \n" + ""; + 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