This commit is contained in:
parent
3fdba645a6
commit
80aa6dc1d9
|
@ -717,8 +717,10 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
// Check if its a pointer to a function
|
// Check if its a pointer to a function
|
||||||
const Token * dtok = Token::findmatch(deleterToken, "& %name%", endDeleterToken);
|
const Token * dtok = Token::findmatch(deleterToken, "& %name%", endDeleterToken);
|
||||||
if (dtok) {
|
if (dtok) {
|
||||||
af = mSettings->library.getDeallocFuncInfo(dtok->tokAt(1));
|
dtok = dtok->next();
|
||||||
} else {
|
af = mSettings->library.getDeallocFuncInfo(dtok);
|
||||||
|
}
|
||||||
|
if (!dtok || !af) {
|
||||||
const Token * tscopeStart = nullptr;
|
const Token * tscopeStart = nullptr;
|
||||||
const Token * tscopeEnd = nullptr;
|
const Token * tscopeEnd = nullptr;
|
||||||
// If the deleter is a lambda, check if it calls the dealloc function
|
// If the deleter is a lambda, check if it calls the dealloc function
|
||||||
|
@ -728,6 +730,13 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
Token::simpleMatch(deleterToken->link()->linkAt(1), ") {")) {
|
Token::simpleMatch(deleterToken->link()->linkAt(1), ") {")) {
|
||||||
tscopeStart = deleterToken->link()->linkAt(1)->tokAt(1);
|
tscopeStart = deleterToken->link()->linkAt(1)->tokAt(1);
|
||||||
tscopeEnd = tscopeStart->link();
|
tscopeEnd = tscopeStart->link();
|
||||||
|
// check user-defined deleter function
|
||||||
|
} else if (dtok && dtok->function()) {
|
||||||
|
const Scope* tscope = dtok->function()->functionScope;
|
||||||
|
if (tscope) {
|
||||||
|
tscopeStart = tscope->bodyStart;
|
||||||
|
tscopeEnd = tscope->bodyEnd;
|
||||||
|
}
|
||||||
// If the deleter is a class, check if class calls the dealloc function
|
// If the deleter is a class, check if class calls the dealloc function
|
||||||
} else if ((dtok = Token::findmatch(deleterToken, "%type%", endDeleterToken)) && dtok->type()) {
|
} else if ((dtok = Token::findmatch(deleterToken, "%type%", endDeleterToken)) && dtok->type()) {
|
||||||
const Scope * tscope = dtok->type()->classScope;
|
const Scope * tscope = dtok->type()->classScope;
|
||||||
|
@ -743,6 +752,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
if (af)
|
if (af)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else { // there is a deleter, but we can't check it -> assume that it deallocates correctly
|
||||||
|
varInfo->clear();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2012,6 +2012,21 @@ private:
|
||||||
"}", true);
|
"}", true);
|
||||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (error) Mismatching allocation and deallocation: i\n"
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (error) Mismatching allocation and deallocation: i\n"
|
||||||
"[test.cpp:3] -> [test.cpp:4]: (error) Mismatching allocation and deallocation: j\n", errout.str());
|
"[test.cpp:3] -> [test.cpp:4]: (error) Mismatching allocation and deallocation: j\n", errout.str());
|
||||||
|
|
||||||
|
check("static void deleter(int* p) { free(p); }\n" // #11392
|
||||||
|
"void f() {\n"
|
||||||
|
" if (int* p = static_cast<int*>(malloc(4))) {\n"
|
||||||
|
" std::unique_ptr<int, decltype(&deleter)> guard(p, &deleter);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n", true);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f() {\n"
|
||||||
|
" if (int* p = static_cast<int*>(malloc(4))) {\n"
|
||||||
|
" std::unique_ptr<int, decltype(&deleter)> guard(p, &deleter);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n", true);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void smartPointerDeleter() {
|
void smartPointerDeleter() {
|
||||||
|
|
Loading…
Reference in New Issue