Fixed #4236 (False positive: pointer free()d twice - neglecting call to other function)
This commit is contained in:
parent
39a5768e9d
commit
863441afe8
|
@ -506,6 +506,8 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const st
|
||||||
if (dealloc.empty()) {
|
if (dealloc.empty()) {
|
||||||
// possible usage
|
// possible usage
|
||||||
possibleUsage[arg->varId()] = tok->str();
|
possibleUsage[arg->varId()] = tok->str();
|
||||||
|
if (var->second == "dealloc" && arg->previous()->str() == "&")
|
||||||
|
varInfo->erase(arg->varId());
|
||||||
} else if (var->second == "dealloc") {
|
} else if (var->second == "dealloc") {
|
||||||
CheckOther checkOther(_tokenizer, _settings, _errorLogger);
|
CheckOther checkOther(_tokenizer, _settings, _errorLogger);
|
||||||
checkOther.doubleFreeError(tok, arg->str());
|
checkOther.doubleFreeError(tok, arg->str());
|
||||||
|
|
|
@ -2013,6 +2013,8 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
|
||||||
Token *tok = getcode(Tok1, callstack, varid, alloctype, dealloctype, classmember, sz);
|
Token *tok = getcode(Tok1, callstack, varid, alloctype, dealloctype, classmember, sz);
|
||||||
//tok->printOut((std::string("Checkmemoryleak: getcode result for: ") + varname).c_str());
|
//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..
|
// Simplify the code and check if freed memory is used..
|
||||||
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||||
while (Token::Match(tok2, "[;{}] ;"))
|
while (Token::Match(tok2, "[;{}] ;"))
|
||||||
|
@ -2071,7 +2073,7 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
|
||||||
memoryLeak(result, varname, alloctype);
|
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);
|
deallocDeallocError(result->tokAt(2), varname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ private:
|
||||||
TEST_CASE(assign9);
|
TEST_CASE(assign9);
|
||||||
TEST_CASE(assign10);
|
TEST_CASE(assign10);
|
||||||
TEST_CASE(assign11); // #3942: x = a(b(p));
|
TEST_CASE(assign11); // #3942: x = a(b(p));
|
||||||
|
TEST_CASE(assign12); // #4236: FP. bar(&x);
|
||||||
|
|
||||||
TEST_CASE(deallocuse1);
|
TEST_CASE(deallocuse1);
|
||||||
TEST_CASE(deallocuse2);
|
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());
|
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() {
|
void deallocuse1() {
|
||||||
check("void f(char *p) {\n"
|
check("void f(char *p) {\n"
|
||||||
" free(p);\n"
|
" free(p);\n"
|
||||||
|
|
|
@ -281,6 +281,7 @@ private:
|
||||||
// free a free'd pointer
|
// free a free'd pointer
|
||||||
TEST_CASE(freefree1);
|
TEST_CASE(freefree1);
|
||||||
TEST_CASE(freefree2);
|
TEST_CASE(freefree2);
|
||||||
|
TEST_CASE(freefree3); // #4236 - FP. bar(&p)
|
||||||
TEST_CASE(strcpy_result_assignment);
|
TEST_CASE(strcpy_result_assignment);
|
||||||
TEST_CASE(strcat_result_assignment);
|
TEST_CASE(strcat_result_assignment);
|
||||||
|
|
||||||
|
@ -3020,6 +3021,17 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void strcpy_result_assignment() {
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue