Skip to content

Commit

Permalink
fix #11542 and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ludviggunne committed Sep 11, 2024
1 parent 22f7c0a commit a117b8d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
40 changes: 30 additions & 10 deletions lib/checkleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,23 +372,43 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
const Token *dst = args[0];
const Token *src = args[1];

// check that arguments are pointers
bool dstIsPtr = dst->isVariable() && dst->variable()->isPointer();
if (!dstIsPtr && dst->str() == "&") {
// check that dst arg is pointer to pointer
int dstIndirectionLevel = 0;
while (dst->str() == "*") {
dst = dst->astOperand1();
dstIsPtr = true;
dstIndirectionLevel--;
}
bool srcIsPtr = src->isVariable() && src->variable()->isPointer();
if (!srcIsPtr && src->str() == "&") {
if (dst->str() == "&") {
dst = dst->astOperand1();
dstIndirectionLevel++;
}
if (!dst->isVariable())
continue;
if (dstIndirectionLevel + dst->variable()->valueType()->pointer != 2)
continue;

// check that src arg is pointer to pointer
int srcIndirectionLevel = 0;
while (src->str() == "*") {
src = src->astOperand1();
srcIsPtr = true;
srcIndirectionLevel--;
}
if (!dstIsPtr || !srcIsPtr) {
if (src->str() == "&") {
src = src->astOperand1();
srcIndirectionLevel++;
}
if (!src->isVariable())
continue;
if (srcIndirectionLevel + src->variable()->valueType()->pointer != 2)
continue;

if (!dst->variable()->isArgument()) {
varInfo.alloctype[dst->varId()].status = VarInfo::AllocStatus::ALLOC;
}

// TODO: check that dst and src are pointers to pointers
// TODO: move ownership from src to dst
// no multivariable checking currently (see assignment below)
// treat source pointer as unallocated
varInfo.erase(src->varId());
}

auto isAssignment = [](const Token* varTok) -> const Token* {
Expand Down
23 changes: 23 additions & 0 deletions test/testleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class TestLeakAutoVar : public TestFixture {
TEST_CASE(assign25);
TEST_CASE(assign26);

TEST_CASE(memcpyWithPtr1); // #11542
TEST_CASE(memcpyWithPtr2);

TEST_CASE(isAutoDealloc);

TEST_CASE(realloc1);
Expand Down Expand Up @@ -631,6 +634,26 @@ class TestLeakAutoVar : public TestFixture {
ASSERT_EQUALS("", errout_str());
}

void memcpyWithPtr1() { // #11542
check("#include <string.h>\n"
"void f(char** old, char* value) {\n"
" char *str = strdup(value);\n"
" memcpy(old, &str, sizeof(char*));\n"
"}\n");
ASSERT_EQUALS("", errout_str());
}

void memcpyWithPtr2() {
check("#include <string.h>\n"
"void f(char* value) {\n"
" char *old = NULL;\n"
" char *str = strdup(value);\n"
" memcpy(&old, &str, sizeof(char*));\n"
"}\n");
// TODO: make this fail
ASSERT_EQUALS("", errout_str());
}

void isAutoDealloc() {
check("void f() {\n"
" char *p = new char[100];"
Expand Down

0 comments on commit a117b8d

Please sign in to comment.