Skip to content

Commit

Permalink
use configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
ludviggunne committed Oct 22, 2024
1 parent 4d43009 commit 42d8fed
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 52 deletions.
76 changes: 32 additions & 44 deletions lib/checkleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,52 +363,40 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
while (Token::Match(ftok, "%name% :: %name%"))
ftok = ftok->tokAt(2);

// memcpy / memmove
if (Token::Match(varTok, "memcpy|memmove")) {
const std::vector<const Token*> args = getArguments(varTok);
// too few args for memcpy / memmove call
if (args.size() < 3)
continue;
const Token *dst = args[0];
const Token *src = args[1];

// check that dst arg is pointer to pointer
int dstIndirectionLevel = 0;
while (dst->str() == "*") {
dst = dst->astOperand1();
dstIndirectionLevel--;
}
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();
srcIndirectionLevel--;
}
if (src->str() == "&") {
src = src->astOperand1();
srcIndirectionLevel++;
if (const Library::Function *libFunc = mSettings->library.getFunction(ftok)) {
using ArgumentChecks = Library::ArgumentChecks;
using Direction = ArgumentChecks::Direction;
const std::vector<const Token *> args = getArguments(ftok);
const std::map<int, ArgumentChecks> &argChecks = libFunc->argumentChecks;
bool hasOutParam = false;
for (const auto &pair : argChecks) {
hasOutParam |= std::any_of(pair.second.direction.cbegin(), pair.second.direction.cend(), [&](const Direction dir) {
return dir == Direction::DIR_OUT;
});
if (hasOutParam)
break;
}
if (!src->isVariable())
continue;
if (srcIndirectionLevel + src->variable()->valueType()->pointer != 2)
continue;

if (!dst->variable()->isArgument()) {
varInfo.alloctype[dst->varId()].status = VarInfo::AllocStatus::ALLOC;
if (hasOutParam) {
for (int i = 0; i < args.size(); i++) {
if (!argChecks.count(i + 1))
continue;
const ArgumentChecks argCheck = argChecks.at(i + 1);
bool isInParam = std::any_of(argCheck.direction.cbegin(), argCheck.direction.cend(), [&](const Direction dir) {
return dir == Direction::DIR_IN;
});
if (!isInParam)
continue;
const Token *varTok = args[i];
int indirect = 0;
while (varTok->isUnaryOp("&")) {
varTok = varTok->astOperand1();
indirect++;
}
if (varTok->isVariable() && indirect) {
varInfo.erase(varTok->varId());
}
}
}

// 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
15 changes: 7 additions & 8 deletions test/testleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ class TestLeakAutoVar : public TestFixture {
TEST_CASE(assign25);
TEST_CASE(assign26);

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

TEST_CASE(isAutoDealloc);

Expand Down Expand Up @@ -636,7 +636,7 @@ class TestLeakAutoVar : public TestFixture {
ASSERT_EQUALS("", errout_str());
}

void memcpyWithPtr1() { // #11542
void memcpy1() { // #11542
const Settings s = settingsBuilder().library("std.cfg").library("posix.cfg").build();
check("void f(char** old, char* value) {\n"
" char *str = strdup(value);\n"
Expand All @@ -645,14 +645,13 @@ class TestLeakAutoVar : public TestFixture {
ASSERT_EQUALS("", errout_str());
}

void memcpyWithPtr2() {
void memcpy2() {
const Settings s = settingsBuilder().library("std.cfg").library("posix.cfg").build();
check("void f(char* value) {\n"
" char *old = NULL;\n"
check("void f(char* old, char* value, size_t len) {\n"
" char *str = strdup(value);\n"
" memcpy(&old, &str, sizeof(char*));\n"
" memcpy(old, str, len);\n"
"}\n", &s);
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: old\n", errout_str());
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: str\n", errout_str());
}

void isAutoDealloc() {
Expand Down

0 comments on commit 42d8fed

Please sign in to comment.