Fixed #6495 (Improve check: uninitialized variable, 3rd function argument)

This commit is contained in:
Daniel Marjamäki 2015-03-14 19:23:33 +01:00
parent 42c4aa1c49
commit fd6bd97972
2 changed files with 35 additions and 11 deletions

View File

@ -57,18 +57,22 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
(value == 0 && Token::Match(firstParam, "0|NULL ,|)"))) {
if (value == 0 && Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && secondParam && secondParam->str() != "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")) {

View File

@ -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<const Token *> 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<const Token *> 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<const Token *> 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<const Token *> 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() {