#6767 False positive: memory leak when variable name is 'new'. Fix handling of new in C code. Move some tests for TokenList to new testtokenlist.cpp

This commit is contained in:
Alexander Mai 2015-06-14 15:49:49 +02:00
parent fff3db48a7
commit 70ba6c4340
4 changed files with 71 additions and 63 deletions

View File

@ -473,7 +473,7 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const Va
return;
for (const Token *arg = tok->tokAt(2); arg; arg = arg->nextArgument()) {
if (arg->str() == "new")
if (_tokenizer->isCPP() && arg->str() == "new")
arg = arg->next();
if (Token::Match(arg, "%var% [-,)]") || Token::Match(arg, "& %var%")) {

View File

@ -109,6 +109,7 @@ private:
TEST_CASE(ptrptr);
TEST_CASE(nestedAllocation);
TEST_CASE(testKeywords); // #6767
}
void check(const char code[], bool cpp = false) {
@ -1139,14 +1140,23 @@ private:
check("void QueueDSMCCPacket(unsigned char *data, int length) {\n"
" unsigned char *dataCopy = malloc(length * sizeof(unsigned char));\n"
" m_dsmccQueue.enqueue(new DSMCCPacket(dataCopy));\n"
"}");
ASSERT_EQUALS("[test.c:4]: (information) --check-library: Function DSMCCPacket() should have <use>/<leak-ignore> configuration\n", errout.str());
"}", true);
ASSERT_EQUALS("[test.cpp:4]: (information) --check-library: Function DSMCCPacket() should have <use>/<leak-ignore> configuration\n", errout.str());
check("void QueueDSMCCPacket(unsigned char *data, int length) {\n"
" unsigned char *dataCopy = malloc(length * sizeof(unsigned char));\n"
" m_dsmccQueue.enqueue(new DSMCCPacket(somethingunrelated));\n"
"}", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: dataCopy\n", errout.str());
}
void testKeywords() {
check("int main(int argc, char **argv) {\n"
" double *new = malloc(1*sizeof(double));\n"
" free(new);\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.c:4]: (error) Memory leak: dataCopy\n", errout.str());
ASSERT_EQUALS("", errout.str());
}
};

View File

@ -206,9 +206,6 @@ private:
TEST_CASE(file2);
TEST_CASE(file3);
TEST_CASE(line1); // Ticket #4408
TEST_CASE(line2); // Ticket #5423
TEST_CASE(doublesharp);
TEST_CASE(isZeroNumber);
@ -3106,61 +3103,6 @@ private:
ASSERT_EQUALS(Path::toNativeSeparators("[c:\\a.h:1]"), tokenizer.list.fileLine(tokenizer.tokens()));
}
void line1() const {
// Test for Ticket #4408
const char code[] = "#file \"c:\\a.h\"\n"
"first\n"
"#line 5\n"
"second\n"
"#line not-a-number\n"
"third\n"
"#line 100 \"i.h\"\n"
"fourth\n"
"fifth\n"
"#endfile\n";
errout.str("");
Settings settings;
TokenList tokenList(&settings);
std::istringstream istr(code);
bool res = tokenList.createTokens(istr, "a.cpp");
ASSERT_EQUALS(res, true);
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
if (tok->str() == "first")
ASSERT_EQUALS(1, tok->linenr());
if (tok->str() == "second")
ASSERT_EQUALS(5, tok->linenr());
if (tok->str() == "third")
ASSERT_EQUALS(7, tok->linenr());
if (tok->str() == "fourth")
ASSERT_EQUALS(100, tok->linenr());
if (tok->str() == "fifth")
ASSERT_EQUALS(101, tok->linenr());
}
}
void line2() const {
const char code[] = "#line 8 \"c:\\a.h\"\n"
"123\n";
errout.str("");
const Settings settings;
// tokenize..
TokenList tokenlist(&settings);
std::istringstream istr(code);
tokenlist.createTokens(istr, "a.cpp");
ASSERT_EQUALS(Path::toNativeSeparators("[c:\\a.h:8]"), tokenlist.fileLine(tokenlist.front()));
}
void doublesharp() {
const char code[] = "a##_##b TEST(var,val) var##_##val = val\n";

View File

@ -17,6 +17,7 @@
*/
#include "testsuite.h"
#include "path.h"
#include "settings.h"
#include "tokenlist.h"
#include "token.h"
@ -31,7 +32,8 @@ public:
private:
void run() {
TEST_CASE(line1); // Ticket #4408
TEST_CASE(line2); // Ticket #5423
TEST_CASE(testaddtoken);
}
@ -44,6 +46,60 @@ private:
ASSERT_EQUALS("9894494448401390090", tokenlist.front()->str());
}
void line1() const {
// Test for Ticket #4408
const char code[] = "#file \"c:\\a.h\"\n"
"first\n"
"#line 5\n"
"second\n"
"#line not-a-number\n"
"third\n"
"#line 100 \"i.h\"\n"
"fourth\n"
"fifth\n"
"#endfile\n";
errout.str("");
Settings settings;
TokenList tokenList(&settings);
std::istringstream istr(code);
bool res = tokenList.createTokens(istr, "a.cpp");
ASSERT_EQUALS(res, true);
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
if (tok->str() == "first")
ASSERT_EQUALS(1, tok->linenr());
if (tok->str() == "second")
ASSERT_EQUALS(5, tok->linenr());
if (tok->str() == "third")
ASSERT_EQUALS(7, tok->linenr());
if (tok->str() == "fourth")
ASSERT_EQUALS(100, tok->linenr());
if (tok->str() == "fifth")
ASSERT_EQUALS(101, tok->linenr());
}
}
void line2() const {
const char code[] = "#line 8 \"c:\\a.h\"\n"
"123\n";
errout.str("");
const Settings settings;
// tokenize..
TokenList tokenlist(&settings);
std::istringstream istr(code);
tokenlist.createTokens(istr, "a.cpp");
ASSERT_EQUALS(Path::toNativeSeparators("[c:\\a.h:8]"), tokenlist.fileLine(tokenlist.front()));
}
};
REGISTER_TEST(TestTokenList)