Fix checkLibraryFunction FPs (#4423)

* Fix checkLibraryFunction FPs

* Fix FP with fclose()

* Format

* Fix FP with reinterpret_cast
This commit is contained in:
chrchr-github 2022-09-02 07:51:10 +02:00 committed by GitHub
parent 79daad8ff4
commit cf52ee098a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 4 deletions

View File

@ -621,6 +621,9 @@ void CheckFunctions::checkLibraryMatchFunctions()
if (tok->function()) if (tok->function())
continue; continue;
if (Token::simpleMatch(tok->astTop(), "throw"))
continue;
if (!mSettings->library.isNotLibraryFunction(tok)) if (!mSettings->library.isNotLibraryFunction(tok))
continue; continue;
@ -631,6 +634,9 @@ void CheckFunctions::checkLibraryMatchFunctions()
if (mSettings->library.functions.find(functionName) != mSettings->library.functions.end()) if (mSettings->library.functions.find(functionName) != mSettings->library.functions.end())
continue; continue;
if (mSettings->library.podtype(tok->expressionString()))
continue;
const Token* start = tok; const Token* start = tok;
while (Token::Match(start->tokAt(-2), "%name% ::")) while (Token::Match(start->tokAt(-2), "%name% ::"))
start = start->tokAt(-2); start = start->tokAt(-2);

View File

@ -777,7 +777,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
rhs = rhs->astParent(); rhs = rhs->astParent();
} }
while (rhs->isCast()) { while (rhs->isCast()) {
rhs = rhs->astOperand1(); rhs = rhs->astOperand2() ? rhs->astOperand2() : rhs->astOperand1();
} }
if (rhs->varId() == tok->varId()) { if (rhs->varId() == tok->varId()) {
// simple assignment // simple assignment
@ -814,7 +814,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
if (returnValue.compare(0, 3, "arg") == 0) if (returnValue.compare(0, 3, "arg") == 0)
// the function returns one of its argument, we need to process a potential assignment // the function returns one of its argument, we need to process a potential assignment
return openingPar; return openingPar;
return openingPar->link(); return isCPPCast(tok->astParent()) ? openingPar : openingPar->link();
} }
return nullptr; return nullptr;
@ -917,8 +917,14 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
const bool isnull = arg->hasKnownIntValue() && arg->values().front().intvalue == 0; const bool isnull = arg->hasKnownIntValue() && arg->values().front().intvalue == 0;
// Is variable allocated? // Is variable allocated?
if (!isnull && (!af || af->arg == argNr)) if (!isnull && (!af || af->arg == argNr)) {
const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName);
VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName);
if (dealloc.type == 0)
changeAllocStatus(varInfo, allocation, tokName, arg); changeAllocStatus(varInfo, allocation, tokName, arg);
else
changeAllocStatus(varInfo, dealloc, tokName, arg);
}
} }
// Check smart pointer // Check smart pointer
else if (Token::Match(arg, "%name% < %type%") && mSettings->library.isSmartPointer(argTypeStartTok)) { else if (Token::Match(arg, "%name% < %type%") && mSettings->library.isSmartPointer(argTypeStartTok)) {

View File

@ -1831,9 +1831,18 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(std::uint64_t& u) {\n"
" u = std::uint32_t(u) * std::uint64_t(100);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f() { throw(1); }\n"); // #8958 check("void f() { throw(1); }\n"); // #8958
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("using namespace std;\n"
"void f() { throw range_error(\"abc\"); }\n");
ASSERT_EQUALS("", errout.str());
check("class C {\n" // #9002 check("class C {\n" // #9002
"public:\n" "public:\n"
" static int f() { return 1; }\n" " static int f() { return 1; }\n"

View File

@ -2432,6 +2432,24 @@ private:
" asm goto(\"assembler code\");\n" " asm goto(\"assembler code\");\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" FILE* p = fopen(\"abc.txt\", \"r\");\n"
" if (fclose(p) != 0) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct S;\n"
"void f(int a, int b, S*& p) {\n"
" if (a == -1) {\n"
" FILE* file = fopen(\"abc.txt\", \"r\");\n"
" }\n"
" if (b) {\n"
" void* buf = malloc(10);\n"
" p = reinterpret_cast<S*>(buf);\n"
" }\n"
"}\n", /*cpp*/ true);
ASSERT_EQUALS("[test.cpp:5]: (error) Resource leak: file\n", errout.str());
} }
void ptrptr() { void ptrptr() {