Skip to content

Commit 7842ae4

Browse files
Fix #11043 FN: memleak posix getline / #12297 FP: memleak (#6103)
1 parent f97bab8 commit 7842ae4

4 files changed

Lines changed: 57 additions & 9 deletions

File tree

lib/checkleakautovar.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -987,10 +987,11 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
987987

988988
if (Token::Match(arg, "%var% [-,)] !!.") || Token::Match(arg, "& %var% !!.")) {
989989
// goto variable
990-
if (arg->str() == "&")
990+
const bool isAddressOf = arg->str() == "&";
991+
if (isAddressOf)
991992
arg = arg->next();
992993

993-
const bool isnull = arg->hasKnownIntValue() && arg->values().front().intvalue == 0;
994+
const bool isnull = !isAddressOf && (arg->hasKnownIntValue() && arg->values().front().intvalue == 0);
994995

995996
// Is variable allocated?
996997
if (!isnull && (!af || af->arg == argNr)) {
@@ -1000,7 +1001,9 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
10001001
if (mSettings->library.getDeallocFuncInfo(tokName)) {
10011002
changeAllocStatus(varInfo, dealloc.type == 0 ? allocation : dealloc, tokName, arg);
10021003
}
1003-
if (allocFunc->arg == argNr && !(arg->variable() && arg->variable()->isArgument() && arg->valueType() && arg->valueType()->pointer > 1)) {
1004+
if (allocFunc->arg == argNr &&
1005+
!(arg->variable() && arg->variable()->isArgument() && arg->valueType() && arg->valueType()->pointer > 1) &&
1006+
(isAddressOf || (arg->valueType() && arg->valueType()->pointer == 2))) {
10041007
leakIfAllocated(arg, varInfo);
10051008
VarInfo::AllocInfo& varAlloc = varInfo.alloctype[arg->varId()];
10061009
varAlloc.type = allocFunc->groupId;

test/cfg/posix.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,12 +1035,13 @@ void nullPointer_pthread_create() // #12396
10351035
pthread_create(&thread, NULL, (void* (*)(void*))f_returns_NULL, NULL);
10361036
}
10371037

1038-
void memleak_getaddrinfo()
1038+
void memleak_getaddrinfo() // #6994
10391039
{
1040-
//TODO: nothing to report yet, see http://sourceforge.net/p/cppcheck/discussion/general/thread/d9737d5d/
10411040
struct addrinfo * res=NULL;
10421041
getaddrinfo("node", NULL, NULL, &res);
10431042
freeaddrinfo(res);
1043+
getaddrinfo("node", NULL, NULL, &res);
1044+
// cppcheck-suppress memleak
10441045
}
10451046

10461047
void memleak_mmap(int fd)
@@ -1058,6 +1059,17 @@ void * memleak_mmap2() // #8327
10581059
return NULL;
10591060
}
10601061

1062+
void memleak_getline() { // #11043
1063+
char *line = NULL;
1064+
size_t size = 0;
1065+
getline(&line, &size, stdin);
1066+
// cppcheck-suppress memleak
1067+
line = NULL;
1068+
getline(&line, &size, stdin);
1069+
// cppcheck-suppress memleak
1070+
line = NULL;
1071+
}
1072+
10611073
void * identicalCondition_mmap(int fd, size_t size) // #9940
10621074
{
10631075
void* buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

test/cfg/windows.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ void memleak_AllocateAndInitializeSid()
572572
PSID pEveryoneSID = NULL;
573573
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
574574
AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID);
575-
// TODO: enable when #6994 is implemented cppcheck-suppress memleak
575+
// cppcheck-suppress memleak
576576
}
577577

578578
void memleak_HeapAlloc()

test/testleakautovar.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828
#include <string>
2929
#include <vector>
3030

31-
class TestLeakAutoVarStrcpy;
32-
class TestLeakAutoVarWindows;
33-
3431
class TestLeakAutoVar : public TestFixture {
3532
public:
3633
TestLeakAutoVar() : TestFixture("TestLeakAutoVar") {}
@@ -3291,3 +3288,39 @@ class TestLeakAutoVarWindows : public TestFixture {
32913288
};
32923289

32933290
REGISTER_TEST(TestLeakAutoVarWindows)
3291+
3292+
class TestLeakAutoVarPosix : public TestFixture {
3293+
public:
3294+
TestLeakAutoVarPosix() : TestFixture("TestLeakAutoVarPosix") {}
3295+
3296+
private:
3297+
const Settings settings = settingsBuilder().library("std.cfg").library("posix.cfg").build();
3298+
3299+
void check_(const char* file, int line, const char code[]) {
3300+
// Clear the error buffer..
3301+
errout.str("");
3302+
3303+
// Tokenize..
3304+
Tokenizer tokenizer(settings, this);
3305+
std::istringstream istr(code);
3306+
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
3307+
3308+
// Check for leaks..
3309+
runChecks<CheckLeakAutoVar>(tokenizer, this);
3310+
}
3311+
3312+
void run() override {
3313+
TEST_CASE(memleak_getline);
3314+
}
3315+
3316+
void memleak_getline() {
3317+
check("void f(std::ifstream &is) {\n" // #12297
3318+
" std::string str;\n"
3319+
" if (getline(is, str, 'x').good()) {};\n"
3320+
" if (!getline(is, str, 'x').good()) {};\n"
3321+
"}\n");
3322+
ASSERT_EQUALS("", errout.str());
3323+
}
3324+
};
3325+
3326+
REGISTER_TEST(TestLeakAutoVarPosix)

0 commit comments

Comments
 (0)