Fix #11392 FP mismatchAllocDealloc with std::unique_ptr and custom deleter (#4585)

This commit is contained in:
chrchr-github 2022-11-18 19:45:25 +01:00 committed by GitHub
parent 3fdba645a6
commit 80aa6dc1d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 2 deletions

View File

@ -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;
}
}
}

View File

@ -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() {