Fixed #4236 (False positive: pointer free()d twice - neglecting call to other function)

This commit is contained in:
Daniel Marjamäki 2012-10-25 19:41:18 +02:00
parent 39a5768e9d
commit 863441afe8
4 changed files with 28 additions and 1 deletions

View File

@ -506,6 +506,8 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const st
if (dealloc.empty()) {
// possible usage
possibleUsage[arg->varId()] = tok->str();
if (var->second == "dealloc" && arg->previous()->str() == "&")
varInfo->erase(arg->varId());
} else if (var->second == "dealloc") {
CheckOther checkOther(_tokenizer, _settings, _errorLogger);
checkOther.doubleFreeError(tok, arg->str());

View File

@ -2013,6 +2013,8 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
Token *tok = getcode(Tok1, callstack, varid, alloctype, dealloctype, classmember, sz);
//tok->printOut((std::string("Checkmemoryleak: getcode result for: ") + varname).c_str());
const bool use_addr = bool(Token::findsimplematch(tok, "&use") != NULL);
// Simplify the code and check if freed memory is used..
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
while (Token::Match(tok2, "[;{}] ;"))
@ -2071,7 +2073,7 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
memoryLeak(result, varname, alloctype);
}
else if ((result = Token::findsimplematch(tok, "dealloc ; dealloc ;")) != NULL) {
else if (!use_addr && (result = Token::findsimplematch(tok, "dealloc ; dealloc ;")) != NULL) {
deallocDeallocError(result->tokAt(2), varname);
}

View File

@ -44,6 +44,7 @@ private:
TEST_CASE(assign9);
TEST_CASE(assign10);
TEST_CASE(assign11); // #3942: x = a(b(p));
TEST_CASE(assign12); // #4236: FP. bar(&x);
TEST_CASE(deallocuse1);
TEST_CASE(deallocuse2);
@ -217,6 +218,16 @@ private:
ASSERT_EQUALS("[test.c:4]: (information) b configuration is needed to establish if there is a leak or not\n", errout.str());
}
void assign12() { // #4236: FP. bar(&x)
check("void f() {\n"
" char *p = malloc(10);\n"
" free(p);\n"
" bar(&p);\n"
" free(p);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void deallocuse1() {
check("void f(char *p) {\n"
" free(p);\n"

View File

@ -281,6 +281,7 @@ private:
// free a free'd pointer
TEST_CASE(freefree1);
TEST_CASE(freefree2);
TEST_CASE(freefree3); // #4236 - FP. bar(&p)
TEST_CASE(strcpy_result_assignment);
TEST_CASE(strcat_result_assignment);
@ -3020,6 +3021,17 @@ private:
ASSERT_EQUALS("", errout.str());
}
void freefree3() {
check("void foo()\n"
"{\n"
" char *p = malloc(10);\n"
" free(p);\n"
" bar(&p);\n"
" free(p);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void strcpy_result_assignment() {
check("void foo()\n"
"{\n"