Skip to content

Commit 7bf6b35

Browse files
Fix #11616 false negative: functionConst (#4887)
1 parent 5791561 commit 7bf6b35

5 files changed

Lines changed: 32 additions & 11 deletions

File tree

lib/checkclass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2328,7 +2328,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
23282328
tok = tok->link();
23292329
else if ((tok->isName() && isMemberVar(scope, tok)) || (tok->isUnaryOp("&") && (tok = tok->astOperand1()) && isMemberVar(scope, tok))) {
23302330
const Variable* var = tok->variable();
2331-
if ((!var || !var->isMutable()) && mayModifyArgs)
2331+
if ((!var || (!var->isMutable() && !var->isConst())) && mayModifyArgs)
23322332
return false; // TODO: Only bailout if function takes argument as non-const reference
23332333
}
23342334
}

lib/checkleakautovar.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ void VarInfo::possibleUsageAll(const std::string &functionName)
141141
}
142142

143143

144-
void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, int type)
144+
void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, int type) const
145145
{
146146
const CheckMemoryLeak checkmemleak(mTokenizer, mErrorLogger, mSettings);
147147
if (Library::isresource(type))
@@ -150,14 +150,14 @@ void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, i
150150
checkmemleak.memleakError(tok, varname);
151151
}
152152

153-
void CheckLeakAutoVar::mismatchError(const Token *deallocTok, const Token *allocTok, const std::string &varname)
153+
void CheckLeakAutoVar::mismatchError(const Token *deallocTok, const Token *allocTok, const std::string &varname) const
154154
{
155155
const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings);
156156
const std::list<const Token *> callstack = { allocTok, deallocTok };
157157
c.mismatchAllocDealloc(callstack, varname);
158158
}
159159

160-
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname)
160+
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname) const
161161
{
162162
const CheckMemoryLeak c(mTokenizer, mErrorLogger, mSettings);
163163
c.deallocuseError(tok, varname);
@@ -842,7 +842,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
842842
}
843843

844844

845-
void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok)
845+
void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok) const
846846
{
847847
const Library::AllocFunc* f = mSettings->library.getReallocFuncInfo(fTok);
848848
if (f && f->arg == -1 && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(fTok)) {

lib/checkleakautovar.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,17 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check {
144144
void changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg);
145145

146146
/** update allocation status if reallocation function */
147-
void changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok);
147+
void changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok) const;
148148

149149
/** return. either "return" or end of variable scope is seen */
150150
void ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope = false);
151151

152152
/** if variable is allocated then there is a leak */
153153
void leakIfAllocated(const Token *vartok, const VarInfo &varInfo);
154154

155-
void leakError(const Token* tok, const std::string &varname, int type);
156-
void mismatchError(const Token* deallocTok, const Token* allocTok, const std::string &varname);
157-
void deallocUseError(const Token *tok, const std::string &varname);
155+
void leakError(const Token* tok, const std::string &varname, int type) const;
156+
void mismatchError(const Token* deallocTok, const Token* allocTok, const std::string &varname) const;
157+
void deallocUseError(const Token *tok, const std::string &varname) const;
158158
void deallocReturnError(const Token *tok, const Token *deallocTok, const std::string &varname);
159159
void doubleFreeError(const Token *tok, const Token *prevFreeTok, const std::string &varname, int type);
160160

lib/symboldatabase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ class CPPCHECKLIB SymbolDatabase {
14541454
nonneg int sizeOfType(const Token *type) const;
14551455

14561456
/** Set array dimensions when valueflow analysis is completed */
1457-
void setArrayDimensionsUsingValueFlow();
1457+
void setArrayDimensionsUsingValueFlow(); // cppcheck-suppress functionConst // has side effects
14581458

14591459
void clangSetVariables(const std::vector<const Variable *> &variableList);
14601460
void createSymbolDatabaseExprIds();

test/testclass.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class TestClass : public TestFixture {
198198
TEST_CASE(const82); // ticket #11513
199199
TEST_CASE(const83);
200200
TEST_CASE(const84);
201+
TEST_CASE(const85);
201202

202203
TEST_CASE(const_handleDefaultParameters);
203204
TEST_CASE(const_passThisToMemberOfOtherClass);
@@ -6361,7 +6362,27 @@ class TestClass : public TestFixture {
63616362
ASSERT_EQUALS("", errout.str());
63626363
}
63636364

6364-
void const84() { // #11618
6365+
void const84() {
6366+
checkConst("class S {};\n" // #11616
6367+
"struct T {\n"
6368+
" T(const S*);\n"
6369+
" T(const S&);\n"
6370+
"};\n"
6371+
"struct C {\n"
6372+
" const S s;\n"
6373+
" void f1() {\n"
6374+
" T t(&s);\n"
6375+
" }\n"
6376+
" void f2() {\n"
6377+
" T t(s);\n"
6378+
" }\n"
6379+
"};\n");
6380+
ASSERT_EQUALS("[test.cpp:8]: (style, inconclusive) Technically the member function 'C::f1' can be const.\n"
6381+
"[test.cpp:11]: (style, inconclusive) Technically the member function 'C::f2' can be const.\n",
6382+
errout.str());
6383+
}
6384+
6385+
void const85() { // #11618
63656386
checkConst("struct S {\n"
63666387
" int a[2], b[2];\n"
63676388
" void f() { f(a, b); }\n"

0 commit comments

Comments
 (0)