Fix #9652 (fp memleak with function call with cast)

When the first argument was (void *)(1), at the start of the second
iteration, arg was pointing to the "1", which caused problems for
nextArgument(), which saw the ")" as the next token and returned
nullptr, signalling that there are no more arguments.

Instead, save the first token in the argument, which makes
nextArgument() do the right thing.
This commit is contained in:
Rikard Falkeborn 2020-07-07 23:46:24 +02:00
parent 6c90de0101
commit 4996ec190e
2 changed files with 45 additions and 1 deletions

View File

@ -856,7 +856,8 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
}
int argNr = 1;
for (const Token *arg = tokFirstArg; arg; arg = arg->nextArgument()) {
for (const Token *funcArg = tokFirstArg; funcArg; funcArg = funcArg->nextArgument()) {
const Token* arg = funcArg;
if (mTokenizer->isCPP() && arg->str() == "new") {
arg = arg->next();
if (Token::simpleMatch(arg, "( std :: nothrow )"))

View File

@ -184,6 +184,8 @@ private:
TEST_CASE(smartPtrInContainer); // #8262
TEST_CASE(recursiveCountLimit); // #5872 #6157 #9097
TEST_CASE(functionCallCastConfig); // #9652
}
void check(const char code[], bool cpp = false) {
@ -202,6 +204,22 @@ private:
c.runChecks(&tokenizer, &settings, this);
}
void check(const char code[], Settings & settings) {
// Clear the error buffer..
errout.str("");
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
// Check for leaks..
CheckLeakAutoVar c;
settings.checkLibrary = true;
settings.addEnabled("information");
c.runChecks(&tokenizer, &settings, this);
}
void checkP(const char code[], bool cpp = false) {
// Clear the error buffer..
errout.str("");
@ -2023,6 +2041,31 @@ private:
"}"));
}
void functionCallCastConfig() { // #9652
Settings settingsFunctionCall = settings;
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def format=\"2\">\n"
" <function name=\"free_func\">\n"
" <noreturn>false</noreturn>\n"
" <arg nr=\"1\">\n"
" <not-uninit/>\n"
" </arg>\n"
" <arg nr=\"2\">\n"
" <not-uninit/>\n"
" </arg>\n"
" </function>\n"
"</def>";
tinyxml2::XMLDocument doc;
doc.Parse(xmldata, sizeof(xmldata));
settingsFunctionCall.library.load(doc);
check("void test_func()\n"
"{\n"
" char * buf = malloc(4);\n"
" free_func((void *)(1), buf);\n"
"}", settingsFunctionCall);
ASSERT_EQUALS("[test.cpp:5]: (information) --check-library: Function free_func() should have <use>/<leak-ignore> configuration\n", errout.str());
}
};
REGISTER_TEST(TestLeakAutoVar)