Fix #9861 FN: "static" not suggested for non-const method (#4101)

* Fix #9861 FN: "static" not suggested for non-const method

* Format

* Make functions static

* static
This commit is contained in:
chrchr-github 2022-05-11 20:01:22 +02:00 committed by GitHub
parent 63a1698335
commit e7e8b1baf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 35 deletions

View File

@ -1988,8 +1988,7 @@ void CheckClass::checkConst()
if (func.isFriend() || func.isStatic() || func.hasVirtualSpecifier()) if (func.isFriend() || func.isStatic() || func.hasVirtualSpecifier())
continue; continue;
// don't warn when returning non-const pointer/reference // don't suggest const when returning non-const pointer/reference, but still suggest static
{
auto isPointerOrReference = [this](const Token* start, const Token* end) -> bool { auto isPointerOrReference = [this](const Token* start, const Token* end) -> bool {
bool inTemplArgList = false, isConstTemplArg = false; bool inTemplArgList = false, isConstTemplArg = false;
for (const Token* tok = start; tok != end; tok = tok->next()) { for (const Token* tok = start; tok != end; tok = tok->next()) {
@ -2015,10 +2014,7 @@ void CheckClass::checkConst()
return false; return false;
}; };
if (isPointerOrReference(func.retDef, func.tokenDef)) const bool returnsPtrOrRef = isPointerOrReference(func.retDef, func.tokenDef);
continue;
}
if (func.isOperator()) { // Operator without return type: conversion operator if (func.isOperator()) { // Operator without return type: conversion operator
const std::string& opName = func.tokenDef->str(); const std::string& opName = func.tokenDef->str();
@ -2043,7 +2039,8 @@ void CheckClass::checkConst()
if (!checkConstFunc(scope, &func, memberAccessed)) if (!checkConstFunc(scope, &func, memberAccessed))
continue; continue;
if (func.isConst() && (memberAccessed || func.isOperator())) const bool suggestStatic = !memberAccessed && !func.isOperator();
if ((returnsPtrOrRef || func.isConst()) && !suggestStatic)
continue; continue;
std::string classname = scope->className; std::string classname = scope->className;
@ -2062,9 +2059,9 @@ void CheckClass::checkConst()
functionName += "]"; functionName += "]";
if (func.isInline()) if (func.isInline())
checkConstError(func.token, classname, functionName, !memberAccessed && !func.isOperator()); checkConstError(func.token, classname, functionName, suggestStatic);
else // not inline else // not inline
checkConstError2(func.token, func.tokenDef, classname, functionName, !memberAccessed && !func.isOperator()); checkConstError2(func.token, func.tokenDef, classname, functionName, suggestStatic);
} }
} }
} }

View File

@ -65,7 +65,7 @@ struct ReverseTraversal {
return true; return true;
} }
Token* getParentFunction(Token* tok) static Token* getParentFunction(Token* tok)
{ {
if (!tok) if (!tok)
return nullptr; return nullptr;
@ -90,7 +90,7 @@ struct ReverseTraversal {
return nullptr; return nullptr;
} }
Token* getTopFunction(Token* tok) static Token* getTopFunction(Token* tok)
{ {
if (!tok) if (!tok)
return nullptr; return nullptr;

View File

@ -303,7 +303,7 @@ public:
* '; int *p(0);' => '; int *p = 0;' * '; int *p(0);' => '; int *p = 0;'
*/ */
void simplifyInitVar(); void simplifyInitVar();
Token * initVar(Token * tok); static Token* initVar(Token* tok);
/** /**
* Simplify easy constant '?:' operation * Simplify easy constant '?:' operation

View File

@ -195,6 +195,7 @@ private:
TEST_CASE(const76); // ticket #10825 TEST_CASE(const76); // ticket #10825
TEST_CASE(const77); // ticket #10307, #10311 TEST_CASE(const77); // ticket #10307, #10311
TEST_CASE(const78); // ticket #10315 TEST_CASE(const78); // ticket #10315
TEST_CASE(const79); // ticket #9861
TEST_CASE(const_handleDefaultParameters); TEST_CASE(const_handleDefaultParameters);
TEST_CASE(const_passThisToMemberOfOtherClass); TEST_CASE(const_passThisToMemberOfOtherClass);
TEST_CASE(assigningPointerToPointerIsNotAConstOperation); TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
@ -6068,6 +6069,17 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void const79() { // #9861
checkConst("class A {\n"
"public:\n"
" char* f() {\n"
" return nullptr;\n"
" }\n"
"};\n");
ASSERT_EQUALS("[test.cpp:3]: (performance, inconclusive) Technically the member function 'A::f' can be static (but you may consider moving to unnamed namespace).\n",
errout.str());
}
void const_handleDefaultParameters() { void const_handleDefaultParameters() {
checkConst("struct Foo {\n" checkConst("struct Foo {\n"
" void foo1(int i, int j = 0) {\n" " void foo1(int i, int j = 0) {\n"