* Fix #11758 Regression: memleak * Format * Fix #11746 FN: deallocuse * Complete the trifecta
This commit is contained in:
parent
22e67d3534
commit
69116c8386
|
@ -1051,7 +1051,7 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
|
|||
// don't warn if we leave an inner scope
|
||||
if (isEndOfScope && var->scope() && tok != var->scope()->bodyEnd)
|
||||
continue;
|
||||
bool used = false;
|
||||
enum class PtrUsage { NONE, DEREF, PTR } used = PtrUsage::NONE;
|
||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == ";")
|
||||
break;
|
||||
|
@ -1068,19 +1068,25 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
|
|||
tok2 = tok3->next();
|
||||
else if (Token::Match(tok3, "& %varid% . %name%", varid))
|
||||
tok2 = tok3->tokAt(4);
|
||||
else if (Token::simpleMatch(tok3, "*"))
|
||||
tok2 = tok3;
|
||||
else
|
||||
continue;
|
||||
if (Token::Match(tok2, "[});,+[]")) {
|
||||
used = true;
|
||||
if (Token::Match(tok2, "[});,+]")) {
|
||||
used = PtrUsage::PTR;
|
||||
break;
|
||||
}
|
||||
if (Token::Match(tok2, "[|.|*")) {
|
||||
used = PtrUsage::DEREF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// return deallocated pointer
|
||||
if (used && it->second.status == VarInfo::DEALLOC)
|
||||
if (used != PtrUsage::NONE && it->second.status == VarInfo::DEALLOC)
|
||||
deallocReturnError(tok, it->second.allocTok, var->name());
|
||||
|
||||
else if (!used && !it->second.managed() && !var->isReference()) {
|
||||
else if (used != PtrUsage::PTR && !it->second.managed() && !var->isReference()) {
|
||||
const auto use = possibleUsage.find(varid);
|
||||
if (use == possibleUsage.end()) {
|
||||
leakError(tok, var->name(), it->second.type);
|
||||
|
|
|
@ -194,6 +194,7 @@ private:
|
|||
TEST_CASE(return7); // #9343 return (uint8_t*)x
|
||||
TEST_CASE(return8);
|
||||
TEST_CASE(return9);
|
||||
TEST_CASE(return10);
|
||||
|
||||
// General tests: variable type, allocation type, etc
|
||||
TEST_CASE(test1);
|
||||
|
@ -2392,6 +2393,30 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void return10() {
|
||||
check("char f() {\n" // #11758
|
||||
" char* p = (char*)malloc(1);\n"
|
||||
" p[0] = 'x';\n"
|
||||
" return p[0];\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.c:4]: (error) Memory leak: p\n", errout.str());
|
||||
|
||||
check("struct S { int f(); };\n" // #11746
|
||||
"int g() {\n"
|
||||
" S* s = new S;\n"
|
||||
" delete s;\n"
|
||||
" return s->f();\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5]: (error) Returning/dereferencing 's' after it is deallocated / released\n", errout.str());
|
||||
|
||||
check("int f() {\n"
|
||||
" int* p = new int(3);\n"
|
||||
" delete p;\n"
|
||||
" return *p;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (error) Returning/dereferencing 'p' after it is deallocated / released\n", errout.str());
|
||||
}
|
||||
|
||||
void test1() {
|
||||
check("void f(double*&p) {\n" // 3809
|
||||
" p = malloc(0x100);\n"
|
||||
|
|
Loading…
Reference in New Issue