Fix checkLibraryFunction FPs (#4423)
* Fix checkLibraryFunction FPs * Fix FP with fclose() * Format * Fix FP with reinterpret_cast
This commit is contained in:
parent
79daad8ff4
commit
cf52ee098a
|
@ -621,6 +621,9 @@ void CheckFunctions::checkLibraryMatchFunctions()
|
|||
if (tok->function())
|
||||
continue;
|
||||
|
||||
if (Token::simpleMatch(tok->astTop(), "throw"))
|
||||
continue;
|
||||
|
||||
if (!mSettings->library.isNotLibraryFunction(tok))
|
||||
continue;
|
||||
|
||||
|
@ -631,6 +634,9 @@ void CheckFunctions::checkLibraryMatchFunctions()
|
|||
if (mSettings->library.functions.find(functionName) != mSettings->library.functions.end())
|
||||
continue;
|
||||
|
||||
if (mSettings->library.podtype(tok->expressionString()))
|
||||
continue;
|
||||
|
||||
const Token* start = tok;
|
||||
while (Token::Match(start->tokAt(-2), "%name% ::"))
|
||||
start = start->tokAt(-2);
|
||||
|
|
|
@ -777,7 +777,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
|
|||
rhs = rhs->astParent();
|
||||
}
|
||||
while (rhs->isCast()) {
|
||||
rhs = rhs->astOperand1();
|
||||
rhs = rhs->astOperand2() ? rhs->astOperand2() : rhs->astOperand1();
|
||||
}
|
||||
if (rhs->varId() == tok->varId()) {
|
||||
// simple assignment
|
||||
|
@ -814,7 +814,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
|
|||
if (returnValue.compare(0, 3, "arg") == 0)
|
||||
// the function returns one of its argument, we need to process a potential assignment
|
||||
return openingPar;
|
||||
return openingPar->link();
|
||||
return isCPPCast(tok->astParent()) ? openingPar : openingPar->link();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Is variable allocated?
|
||||
if (!isnull && (!af || af->arg == argNr))
|
||||
changeAllocStatus(varInfo, allocation, tokName, arg);
|
||||
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);
|
||||
else
|
||||
changeAllocStatus(varInfo, dealloc, tokName, arg);
|
||||
}
|
||||
}
|
||||
// Check smart pointer
|
||||
else if (Token::Match(arg, "%name% < %type%") && mSettings->library.isSmartPointer(argTypeStartTok)) {
|
||||
|
|
|
@ -1831,9 +1831,18 @@ private:
|
|||
"}\n");
|
||||
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
|
||||
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
|
||||
"public:\n"
|
||||
" static int f() { return 1; }\n"
|
||||
|
|
|
@ -2432,6 +2432,24 @@ private:
|
|||
" asm goto(\"assembler code\");\n"
|
||||
"}\n");
|
||||
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() {
|
||||
|
|
Loading…
Reference in New Issue