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
|
||||
const Token * dtok = Token::findmatch(deleterToken, "& %name%", endDeleterToken);
|
||||
if (dtok) {
|
||||
af = mSettings->library.getDeallocFuncInfo(dtok->tokAt(1));
|
||||
} else {
|
||||
dtok = dtok->next();
|
||||
af = mSettings->library.getDeallocFuncInfo(dtok);
|
||||
}
|
||||
if (!dtok || !af) {
|
||||
const Token * tscopeStart = nullptr;
|
||||
const Token * tscopeEnd = nullptr;
|
||||
// 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), ") {")) {
|
||||
tscopeStart = deleterToken->link()->linkAt(1)->tokAt(1);
|
||||
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
|
||||
} else if ((dtok = Token::findmatch(deleterToken, "%type%", endDeleterToken)) && dtok->type()) {
|
||||
const Scope * tscope = dtok->type()->classScope;
|
||||
|
@ -743,6 +752,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
|||
if (af)
|
||||
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);
|
||||
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());
|
||||
|
||||
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() {
|
||||
|
|
Loading…
Reference in New Issue