parent
5791561a45
commit
7bf6b359b1
|
@ -2328,7 +2328,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
else if ((tok->isName() && isMemberVar(scope, tok)) || (tok->isUnaryOp("&") && (tok = tok->astOperand1()) && isMemberVar(scope, tok))) {
|
else if ((tok->isName() && isMemberVar(scope, tok)) || (tok->isUnaryOp("&") && (tok = tok->astOperand1()) && isMemberVar(scope, tok))) {
|
||||||
const Variable* var = tok->variable();
|
const Variable* var = tok->variable();
|
||||||
if ((!var || !var->isMutable()) && mayModifyArgs)
|
if ((!var || (!var->isMutable() && !var->isConst())) && mayModifyArgs)
|
||||||
return false; // TODO: Only bailout if function takes argument as non-const reference
|
return false; // TODO: Only bailout if function takes argument as non-const reference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ void VarInfo::possibleUsageAll(const std::string &functionName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, int type)
|
void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, int type) const
|
||||||
{
|
{
|
||||||
const CheckMemoryLeak checkmemleak(mTokenizer, mErrorLogger, mSettings);
|
const CheckMemoryLeak checkmemleak(mTokenizer, mErrorLogger, mSettings);
|
||||||
if (Library::isresource(type))
|
if (Library::isresource(type))
|
||||||
|
@ -150,14 +150,14 @@ void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, i
|
||||||
checkmemleak.memleakError(tok, varname);
|
checkmemleak.memleakError(tok, varname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::mismatchError(const Token *deallocTok, const Token *allocTok, const std::string &varname)
|
void CheckLeakAutoVar::mismatchError(const Token *deallocTok, const Token *allocTok, const std::string &varname) const
|
||||||
{
|
{
|
||||||
const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings);
|
const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings);
|
||||||
const std::list<const Token *> callstack = { allocTok, deallocTok };
|
const std::list<const Token *> callstack = { allocTok, deallocTok };
|
||||||
c.mismatchAllocDealloc(callstack, varname);
|
c.mismatchAllocDealloc(callstack, varname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname)
|
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname) const
|
||||||
{
|
{
|
||||||
const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings);
|
const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings);
|
||||||
c.deallocuseError(tok, varname);
|
c.deallocuseError(tok, varname);
|
||||||
|
@ -842,7 +842,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok)
|
void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok) const
|
||||||
{
|
{
|
||||||
const Library::AllocFunc* f = mSettings->library.getReallocFuncInfo(fTok);
|
const Library::AllocFunc* f = mSettings->library.getReallocFuncInfo(fTok);
|
||||||
if (f && f->arg == -1 && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(fTok)) {
|
if (f && f->arg == -1 && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(fTok)) {
|
||||||
|
|
|
@ -144,7 +144,7 @@ private:
|
||||||
void changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg);
|
void changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg);
|
||||||
|
|
||||||
/** update allocation status if reallocation function */
|
/** update allocation status if reallocation function */
|
||||||
void changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok);
|
void changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok) const;
|
||||||
|
|
||||||
/** return. either "return" or end of variable scope is seen */
|
/** return. either "return" or end of variable scope is seen */
|
||||||
void ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope = false);
|
void ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope = false);
|
||||||
|
@ -152,9 +152,9 @@ private:
|
||||||
/** if variable is allocated then there is a leak */
|
/** if variable is allocated then there is a leak */
|
||||||
void leakIfAllocated(const Token *vartok, const VarInfo &varInfo);
|
void leakIfAllocated(const Token *vartok, const VarInfo &varInfo);
|
||||||
|
|
||||||
void leakError(const Token* tok, const std::string &varname, int type);
|
void leakError(const Token* tok, const std::string &varname, int type) const;
|
||||||
void mismatchError(const Token* deallocTok, const Token* allocTok, const std::string &varname);
|
void mismatchError(const Token* deallocTok, const Token* allocTok, const std::string &varname) const;
|
||||||
void deallocUseError(const Token *tok, const std::string &varname);
|
void deallocUseError(const Token *tok, const std::string &varname) const;
|
||||||
void deallocReturnError(const Token *tok, const Token *deallocTok, const std::string &varname);
|
void deallocReturnError(const Token *tok, const Token *deallocTok, const std::string &varname);
|
||||||
void doubleFreeError(const Token *tok, const Token *prevFreeTok, const std::string &varname, int type);
|
void doubleFreeError(const Token *tok, const Token *prevFreeTok, const std::string &varname, int type);
|
||||||
|
|
||||||
|
|
|
@ -1454,7 +1454,7 @@ public:
|
||||||
nonneg int sizeOfType(const Token *type) const;
|
nonneg int sizeOfType(const Token *type) const;
|
||||||
|
|
||||||
/** Set array dimensions when valueflow analysis is completed */
|
/** Set array dimensions when valueflow analysis is completed */
|
||||||
void setArrayDimensionsUsingValueFlow();
|
void setArrayDimensionsUsingValueFlow(); // cppcheck-suppress functionConst // has side effects
|
||||||
|
|
||||||
void clangSetVariables(const std::vector<const Variable *> &variableList);
|
void clangSetVariables(const std::vector<const Variable *> &variableList);
|
||||||
void createSymbolDatabaseExprIds();
|
void createSymbolDatabaseExprIds();
|
||||||
|
|
|
@ -198,6 +198,7 @@ private:
|
||||||
TEST_CASE(const82); // ticket #11513
|
TEST_CASE(const82); // ticket #11513
|
||||||
TEST_CASE(const83);
|
TEST_CASE(const83);
|
||||||
TEST_CASE(const84);
|
TEST_CASE(const84);
|
||||||
|
TEST_CASE(const85);
|
||||||
|
|
||||||
TEST_CASE(const_handleDefaultParameters);
|
TEST_CASE(const_handleDefaultParameters);
|
||||||
TEST_CASE(const_passThisToMemberOfOtherClass);
|
TEST_CASE(const_passThisToMemberOfOtherClass);
|
||||||
|
@ -6361,7 +6362,27 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void const84() { // #11618
|
void const84() {
|
||||||
|
checkConst("class S {};\n" // #11616
|
||||||
|
"struct T {\n"
|
||||||
|
" T(const S*);\n"
|
||||||
|
" T(const S&);\n"
|
||||||
|
"};\n"
|
||||||
|
"struct C {\n"
|
||||||
|
" const S s;\n"
|
||||||
|
" void f1() {\n"
|
||||||
|
" T t(&s);\n"
|
||||||
|
" }\n"
|
||||||
|
" void f2() {\n"
|
||||||
|
" T t(s);\n"
|
||||||
|
" }\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:8]: (style, inconclusive) Technically the member function 'C::f1' can be const.\n"
|
||||||
|
"[test.cpp:11]: (style, inconclusive) Technically the member function 'C::f2' can be const.\n",
|
||||||
|
errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void const85() { // #11618
|
||||||
checkConst("struct S {\n"
|
checkConst("struct S {\n"
|
||||||
" int a[2], b[2];\n"
|
" int a[2], b[2];\n"
|
||||||
" void f() { f(a, b); }\n"
|
" void f() { f(a, b); }\n"
|
||||||
|
|
Loading…
Reference in New Issue