* Fix #9861 FN: "static" not suggested for non-const method * Format * Make functions static * static
This commit is contained in:
parent
63a1698335
commit
e7e8b1baf9
|
@ -1988,37 +1988,33 @@ void CheckClass::checkConst()
|
|||
if (func.isFriend() || func.isStatic() || func.hasVirtualSpecifier())
|
||||
continue;
|
||||
|
||||
// don't warn when returning non-const pointer/reference
|
||||
{
|
||||
auto isPointerOrReference = [this](const Token* start, const Token* end) -> bool {
|
||||
bool inTemplArgList = false, isConstTemplArg = false;
|
||||
for (const Token* tok = start; tok != end; tok = tok->next()) {
|
||||
if (tok->str() == "{") // end of trailing return type
|
||||
return false;
|
||||
if (tok->str() == "<") {
|
||||
if (!tok->link())
|
||||
mSymbolDatabase->debugMessage(tok, "debug", "CheckClass::checkConst found unlinked template argument list '" + tok->expressionString() + "'.");
|
||||
inTemplArgList = true;
|
||||
}
|
||||
else if (tok->str() == ">") {
|
||||
inTemplArgList = false;
|
||||
isConstTemplArg = false;
|
||||
}
|
||||
else if (tok->str() == "const") {
|
||||
if (!inTemplArgList)
|
||||
return false;
|
||||
isConstTemplArg = true;
|
||||
}
|
||||
else if (!isConstTemplArg && Token::Match(tok, "*|&"))
|
||||
return true;
|
||||
// don't suggest const when returning non-const pointer/reference, but still suggest static
|
||||
auto isPointerOrReference = [this](const Token* start, const Token* end) -> bool {
|
||||
bool inTemplArgList = false, isConstTemplArg = false;
|
||||
for (const Token* tok = start; tok != end; tok = tok->next()) {
|
||||
if (tok->str() == "{") // end of trailing return type
|
||||
return false;
|
||||
if (tok->str() == "<") {
|
||||
if (!tok->link())
|
||||
mSymbolDatabase->debugMessage(tok, "debug", "CheckClass::checkConst found unlinked template argument list '" + tok->expressionString() + "'.");
|
||||
inTemplArgList = true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (isPointerOrReference(func.retDef, func.tokenDef))
|
||||
continue;
|
||||
}
|
||||
else if (tok->str() == ">") {
|
||||
inTemplArgList = false;
|
||||
isConstTemplArg = false;
|
||||
}
|
||||
else if (tok->str() == "const") {
|
||||
if (!inTemplArgList)
|
||||
return false;
|
||||
isConstTemplArg = true;
|
||||
}
|
||||
else if (!isConstTemplArg && Token::Match(tok, "*|&"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const bool returnsPtrOrRef = isPointerOrReference(func.retDef, func.tokenDef);
|
||||
|
||||
if (func.isOperator()) { // Operator without return type: conversion operator
|
||||
const std::string& opName = func.tokenDef->str();
|
||||
|
@ -2043,7 +2039,8 @@ void CheckClass::checkConst()
|
|||
if (!checkConstFunc(scope, &func, memberAccessed))
|
||||
continue;
|
||||
|
||||
if (func.isConst() && (memberAccessed || func.isOperator()))
|
||||
const bool suggestStatic = !memberAccessed && !func.isOperator();
|
||||
if ((returnsPtrOrRef || func.isConst()) && !suggestStatic)
|
||||
continue;
|
||||
|
||||
std::string classname = scope->className;
|
||||
|
@ -2062,9 +2059,9 @@ void CheckClass::checkConst()
|
|||
functionName += "]";
|
||||
|
||||
if (func.isInline())
|
||||
checkConstError(func.token, classname, functionName, !memberAccessed && !func.isOperator());
|
||||
checkConstError(func.token, classname, functionName, suggestStatic);
|
||||
else // not inline
|
||||
checkConstError2(func.token, func.tokenDef, classname, functionName, !memberAccessed && !func.isOperator());
|
||||
checkConstError2(func.token, func.tokenDef, classname, functionName, suggestStatic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ struct ReverseTraversal {
|
|||
return true;
|
||||
}
|
||||
|
||||
Token* getParentFunction(Token* tok)
|
||||
static Token* getParentFunction(Token* tok)
|
||||
{
|
||||
if (!tok)
|
||||
return nullptr;
|
||||
|
@ -90,7 +90,7 @@ struct ReverseTraversal {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Token* getTopFunction(Token* tok)
|
||||
static Token* getTopFunction(Token* tok)
|
||||
{
|
||||
if (!tok)
|
||||
return nullptr;
|
||||
|
|
|
@ -303,7 +303,7 @@ public:
|
|||
* '; int *p(0);' => '; int *p = 0;'
|
||||
*/
|
||||
void simplifyInitVar();
|
||||
Token * initVar(Token * tok);
|
||||
static Token* initVar(Token* tok);
|
||||
|
||||
/**
|
||||
* Simplify easy constant '?:' operation
|
||||
|
|
|
@ -195,6 +195,7 @@ private:
|
|||
TEST_CASE(const76); // ticket #10825
|
||||
TEST_CASE(const77); // ticket #10307, #10311
|
||||
TEST_CASE(const78); // ticket #10315
|
||||
TEST_CASE(const79); // ticket #9861
|
||||
TEST_CASE(const_handleDefaultParameters);
|
||||
TEST_CASE(const_passThisToMemberOfOtherClass);
|
||||
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
|
||||
|
@ -6068,6 +6069,17 @@ private:
|
|||
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() {
|
||||
checkConst("struct Foo {\n"
|
||||
" void foo1(int i, int j = 0) {\n"
|
||||
|
|
Loading…
Reference in New Issue