This was most likely introduced when the checks were changed to run on the full tokenlist instead of the simplified one. Take care to warn about cases where casts destroy the pointer, such as uint8_t f() { void* x = malloc(1); return (uint8_t)x; }
This commit is contained in:
parent
049f6475ee
commit
007b5d3e8d
|
@ -930,13 +930,21 @@ void CheckLeakAutoVar::ret(const Token *tok, const VarInfo &varInfo)
|
|||
if (var) {
|
||||
bool used = false;
|
||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == ";")
|
||||
if (tok2->str() == ";" || Token::simpleMatch(tok2, "return ;"))
|
||||
break;
|
||||
if (Token::Match(tok2, "return|(|{|, %varid% [});,]", varid)) {
|
||||
used = true;
|
||||
break;
|
||||
}
|
||||
if (Token::Match(tok2, "return|(|{|, & %varid% . %name% [});,]", varid)) {
|
||||
if (!Token::Match(tok2, "return|(|{|,"))
|
||||
continue;
|
||||
|
||||
tok2 = tok2->next();
|
||||
while (tok2 && tok2->isCast() && (tok2->valueType()->pointer || (tok2->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
|
||||
tok2 = tok2->astOperand2() ? tok2->astOperand2() : tok2->astOperand1();
|
||||
if (Token::Match(tok2, "%varid%", varid))
|
||||
tok2 = tok2->next();
|
||||
else if (Token::Match(tok2, "& %varid% . %name%", varid))
|
||||
tok2 = tok2->tokAt(4);
|
||||
else
|
||||
continue;
|
||||
if (Token::Match(tok2, "[});,]")) {
|
||||
used = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@ private:
|
|||
TEST_CASE(return4);
|
||||
TEST_CASE(return5);
|
||||
TEST_CASE(return6); // #8282 return {p, p}
|
||||
TEST_CASE(return7); // #9343 return (uint8_t*)x
|
||||
|
||||
// General tests: variable type, allocation type, etc
|
||||
TEST_CASE(test1);
|
||||
|
@ -521,6 +522,16 @@ private:
|
|||
" return p;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(void* p) {\n"
|
||||
" if (a) {\n"
|
||||
" free(p);\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" g(p);\n"
|
||||
" return;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void deallocuse5() { // #4018
|
||||
|
@ -1694,6 +1705,38 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void return7() { // #9343
|
||||
check("uint8_t *f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return (uint8_t *)x;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("uint8_t f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return (uint8_t)x;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n", errout.str());
|
||||
|
||||
check("void** f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return (void**)x;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void* f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return (long long)x;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void* f() {\n"
|
||||
" void *x = malloc(1);\n"
|
||||
" return (void*)(short)x;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n", errout.str());
|
||||
}
|
||||
|
||||
void test1() { // 3809
|
||||
check("void f(double*&p) {\n"
|
||||
" p = malloc(0x100);\n"
|
||||
|
|
Loading…
Reference in New Issue