diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 2c9d8f1c9..52670d1d5 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -57,18 +57,22 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::liststr() != "0") // Only if length (second parameter) is not zero var.push_back(firstParam); - else if (value == 0 && library != nullptr && library->isnullargbad(&tok, 1) && checkNullpointerFunctionCallPlausibility(tok.function(), 1)) - var.push_back(firstParam); - else if (value == 1 && library != nullptr && library->isuninitargbad(&tok, 1)) - var.push_back(firstParam); } - // 2nd parameter.. - if ((value == 0 && Token::Match(secondParam, "0|NULL ,|)")) || (secondParam && secondParam->varId() > 0 && Token::Match(secondParam->next(),"[,)]"))) { - if (value == 0 && library != nullptr && library->isnullargbad(&tok, 2) && checkNullpointerFunctionCallPlausibility(tok.function(), 2)) - var.push_back(secondParam); - else if (value == 1 && library != nullptr && library->isuninitargbad(&tok, 2)) - var.push_back(secondParam); + // Library + if (library) { + const Token *param = tok.tokAt(2); + int argnr = 1; + while (param) { + if (Token::Match(param, "%var% ,|)") || (value==0 && Token::Match(param, "0|NULL ,|)"))) { + if (value == 0 && library->isnullargbad(&tok, argnr) && checkNullpointerFunctionCallPlausibility(tok.function(), argnr)) + var.push_back(param); + else if (value == 1 && library->isuninitargbad(&tok, argnr)) + var.push_back(param); + } + param = param->nextArgument(); + argnr++; + } } if (Token::Match(&tok, "printf|sprintf|snprintf|fprintf|fnprintf|scanf|sscanf|fscanf|wprintf|swprintf|fwprintf|wscanf|swscanf|fwscanf")) { diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 997e87941..e126a9d10 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -2196,7 +2196,7 @@ private: void functioncalllibrary() { Settings settings1; Tokenizer tokenizer(&settings1,this); - std::istringstream code("void f() { int a,b; x(a,b); }"); + std::istringstream code("void f() { int a,b,c; x(a,b,c); }"); tokenizer.tokenize(code,"test.c"); const Token *xtok = Token::findsimplematch(tokenizer.tokens(), "x"); @@ -2206,6 +2206,7 @@ private: Library::ArgumentChecks arg; library.argumentChecks["x"][1] = arg; library.argumentChecks["x"][2] = arg; + library.argumentChecks["x"][3] = arg; std::list null, uninit; CheckNullPointer::parseFunctionCall(*xtok, null, &library, 0U); @@ -2220,6 +2221,7 @@ private: Library::ArgumentChecks arg; library.argumentChecks["x"][1] = arg; library.argumentChecks["x"][2] = arg; + library.argumentChecks["x"][3] = arg; library.argumentChecks["x"][1].notnull = true; std::list null,uninit; @@ -2236,6 +2238,7 @@ private: Library::ArgumentChecks arg; library.argumentChecks["x"][1] = arg; library.argumentChecks["x"][2] = arg; + library.argumentChecks["x"][3] = arg; library.argumentChecks["x"][2].notuninit = true; std::list null,uninit; @@ -2245,6 +2248,23 @@ private: ASSERT_EQUALS(1U, uninit.size()); ASSERT_EQUALS("b", uninit.front()->str()); } + + // for 3rd parameter uninit data is not ok.. + { + Library library; + Library::ArgumentChecks arg; + library.argumentChecks["x"][1] = arg; + library.argumentChecks["x"][2] = arg; + library.argumentChecks["x"][3] = arg; + library.argumentChecks["x"][3].notuninit = true; + + std::list null,uninit; + CheckNullPointer::parseFunctionCall(*xtok, null, &library, 0U); + CheckNullPointer::parseFunctionCall(*xtok, uninit, &library, 1U); + ASSERT_EQUALS(0U, null.size()); + ASSERT_EQUALS(1U, uninit.size()); + ASSERT_EQUALS("c", uninit.front()->str()); + } } void functioncallDefaultArguments() {