* Fix FN functionStatic * Fix FN functionConst, add test * Fix build
This commit is contained in:
parent
055489df5a
commit
82e9c076da
|
@ -2108,12 +2108,12 @@ void CheckClass::checkConst()
|
|||
if (!scope->definedType->derivedFrom.empty() && func.isImplicitlyVirtual(true))
|
||||
continue;
|
||||
|
||||
bool memberAccessed = false;
|
||||
enum MemberAccess memberAccessed = MemberAccess::NONE;
|
||||
// if nothing non-const was found. write error..
|
||||
if (!checkConstFunc(scope, &func, memberAccessed))
|
||||
continue;
|
||||
|
||||
const bool suggestStatic = !memberAccessed && !func.isOperator();
|
||||
const bool suggestStatic = memberAccessed != MemberAccess::MEMBER && !func.isOperator();
|
||||
if ((returnsPtrOrRef || func.isConst()) && !suggestStatic)
|
||||
continue;
|
||||
|
||||
|
@ -2293,7 +2293,7 @@ bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok)
|
|||
|
||||
const std::set<std::string> CheckClass::stl_containers_not_const = { "map", "unordered_map", "std :: map|unordered_map <" }; // start pattern
|
||||
|
||||
bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool& memberAccessed) const
|
||||
bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, MemberAccess& memberAccessed) const
|
||||
{
|
||||
if (mTokenizer->hasIfdef(func->functionScope->bodyStart, func->functionScope->bodyEnd))
|
||||
return false;
|
||||
|
@ -2312,9 +2312,10 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
|
|||
|
||||
auto checkFuncCall = [this, &memberAccessed](const Token* funcTok, const Scope* scope, const Function* func) {
|
||||
if (isMemberFunc(scope, funcTok) && (funcTok->strAt(-1) != "." || Token::simpleMatch(funcTok->tokAt(-2), "this ."))) {
|
||||
if (!isConstMemberFunc(scope, funcTok) && func != funcTok->function())
|
||||
const bool isSelf = func == funcTok->function();
|
||||
if (!isConstMemberFunc(scope, funcTok) && !isSelf)
|
||||
return false;
|
||||
memberAccessed = true;
|
||||
memberAccessed = (isSelf && memberAccessed != MemberAccess::MEMBER) ? MemberAccess::SELF : MemberAccess::MEMBER;
|
||||
}
|
||||
|
||||
if (const Function* f = funcTok->function()) { // check known function
|
||||
|
@ -2361,7 +2362,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
|
|||
// it can be a const function..
|
||||
for (const Token *tok1 = func->functionScope->bodyStart; tok1 && tok1 != func->functionScope->bodyEnd; tok1 = tok1->next()) {
|
||||
if (tok1->isName() && isMemberVar(scope, tok1)) {
|
||||
memberAccessed = true;
|
||||
memberAccessed = MemberAccess::MEMBER;
|
||||
const Variable* v = tok1->variable();
|
||||
if (v && v->isMutable())
|
||||
continue;
|
||||
|
@ -2476,7 +2477,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
|
|||
;
|
||||
} else if (hasOverloadedMemberAccess(end, var->typeScope())) {
|
||||
;
|
||||
} else if (!var->typeScope() || !isConstMemberFunc(var->typeScope(), end))
|
||||
} else if (!var->typeScope() || (end->function() != func && !isConstMemberFunc(var->typeScope(), end)))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -319,7 +319,8 @@ private:
|
|||
bool isMemberVar(const Scope *scope, const Token *tok) const;
|
||||
static bool isMemberFunc(const Scope *scope, const Token *tok);
|
||||
static bool isConstMemberFunc(const Scope *scope, const Token *tok);
|
||||
bool checkConstFunc(const Scope *scope, const Function *func, bool& memberAccessed) const;
|
||||
enum class MemberAccess { NONE, SELF, MEMBER };
|
||||
bool checkConstFunc(const Scope *scope, const Function *func, MemberAccess& memberAccessed) const;
|
||||
|
||||
// constructors helper function
|
||||
/** @brief Information about a member variable. Used when checking for uninitialized variables */
|
||||
|
|
|
@ -6539,8 +6539,8 @@ private:
|
|||
errout.str());
|
||||
}
|
||||
|
||||
void const89() { // #11654
|
||||
checkConst("struct S {\n"
|
||||
void const89() {
|
||||
checkConst("struct S {\n" // #11654
|
||||
" void f(bool b);\n"
|
||||
" int i;\n"
|
||||
"};\n"
|
||||
|
@ -6560,6 +6560,23 @@ private:
|
|||
" f(i);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkConst("struct S {\n" // #11744
|
||||
" S* p;\n"
|
||||
" int f() {\n"
|
||||
" if (p)\n"
|
||||
" return 1 + p->f();\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
" int g(int i) {\n"
|
||||
" if (i > 0)\n"
|
||||
" return i + g(i - 1);\n"
|
||||
" return 0;\n"
|
||||
" }\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'S::f' can be const.\n"
|
||||
"[test.cpp:8]: (performance, inconclusive) Technically the member function 'S::g' can be static (but you may consider moving to unnamed namespace).\n",
|
||||
errout.str());
|
||||
}
|
||||
|
||||
void const90() { // #11637
|
||||
|
|
Loading…
Reference in New Issue