CheckClass: refactored the code, use symboldatabase instead of name comparisons when possible, fixed a FN.
This commit is contained in:
parent
22542e7547
commit
bce15b1ade
|
@ -41,8 +41,7 @@ static const CWE CWE665(665U);
|
||||||
static const CWE CWE758(758U);
|
static const CWE CWE758(758U);
|
||||||
static const CWE CWE762(762U);
|
static const CWE CWE762(762U);
|
||||||
|
|
||||||
static const char * getFunctionTypeName(
|
static const char * getFunctionTypeName(Function::Type type)
|
||||||
Function::Type type)
|
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Function::eConstructor:
|
case Function::eConstructor:
|
||||||
|
@ -873,7 +872,7 @@ void CheckClass::suggestInitializationList(const Token* tok, const std::string&
|
||||||
// ClassCheck: Unused private functions
|
// ClassCheck: Unused private functions
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
static bool checkFunctionUsage(const std::string& name, const Scope* scope)
|
static bool checkFunctionUsage(const Function *privfunc, const Scope* scope)
|
||||||
{
|
{
|
||||||
if (!scope)
|
if (!scope)
|
||||||
return true; // Assume it is used, if scope is not seen
|
return true; // Assume it is used, if scope is not seen
|
||||||
|
@ -882,14 +881,16 @@ static bool checkFunctionUsage(const std::string& name, const Scope* scope)
|
||||||
if (func->functionScope) {
|
if (func->functionScope) {
|
||||||
if (Token::Match(func->tokenDef, "%name% (")) {
|
if (Token::Match(func->tokenDef, "%name% (")) {
|
||||||
for (const Token *ftok = func->tokenDef->tokAt(2); ftok && ftok->str() != ")"; ftok = ftok->next()) {
|
for (const Token *ftok = func->tokenDef->tokAt(2); ftok && ftok->str() != ")"; ftok = ftok->next()) {
|
||||||
if (Token::Match(ftok, "= %name% [(,)]") && ftok->strAt(1) == name)
|
if (Token::Match(ftok, "= %name% [(,)]") && ftok->strAt(1) == privfunc->name())
|
||||||
return true;
|
return true;
|
||||||
if (ftok->str() == "(")
|
if (ftok->str() == "(")
|
||||||
ftok = ftok->link();
|
ftok = ftok->link();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const Token *ftok = func->functionScope->classDef->linkAt(1); ftok != func->functionScope->classEnd; ftok = ftok->next()) {
|
for (const Token *ftok = func->functionScope->classDef->linkAt(1); ftok != func->functionScope->classEnd; ftok = ftok->next()) {
|
||||||
if (ftok->str() == name) // Function used. TODO: Handle overloads
|
if (ftok->function() == privfunc)
|
||||||
|
return true;
|
||||||
|
if (ftok->varId() == 0U && !ftok->function() && ftok->str() == privfunc->name()) // TODO: This condition should be redundant
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if ((func->type != Function::eCopyConstructor &&
|
} else if ((func->type != Function::eCopyConstructor &&
|
||||||
|
@ -900,7 +901,7 @@ static bool checkFunctionUsage(const std::string& name, const Scope* scope)
|
||||||
|
|
||||||
for (std::list<Scope*>::const_iterator i = scope->nestedList.begin(); i != scope->nestedList.end(); ++i) {
|
for (std::list<Scope*>::const_iterator i = scope->nestedList.begin(); i != scope->nestedList.end(); ++i) {
|
||||||
if ((*i)->isClassOrStruct())
|
if ((*i)->isClassOrStruct())
|
||||||
if (checkFunctionUsage(name, *i)) // Check nested classes, which can access private functions of their base
|
if (checkFunctionUsage(privfunc, *i)) // Check nested classes, which can access private functions of their base
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,7 +911,7 @@ static bool checkFunctionUsage(const std::string& name, const Scope* scope)
|
||||||
if (tok)
|
if (tok)
|
||||||
tok = tok->tokAt(2);
|
tok = tok->tokAt(2);
|
||||||
while (tok && tok->str() != ";") {
|
while (tok && tok->str() != ";") {
|
||||||
if (tok->str() == name && (tok->strAt(-1) == "." || tok->strAt(-2) == scope->className))
|
if (tok->function() == privfunc)
|
||||||
return true;
|
return true;
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
}
|
}
|
||||||
|
@ -952,20 +953,19 @@ void CheckClass::privateFunctions()
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!privateFuncs.empty()) {
|
while (!privateFuncs.empty()) {
|
||||||
const std::string& funcName = privateFuncs.front()->tokenDef->str();
|
|
||||||
// Check that all private functions are used
|
// Check that all private functions are used
|
||||||
bool used = checkFunctionUsage(funcName, scope); // Usage in this class
|
bool used = checkFunctionUsage(privateFuncs.front(), scope); // Usage in this class
|
||||||
// Check in friend classes
|
// Check in friend classes
|
||||||
const std::list<Type::FriendInfo>& friendList = scope->definedType->friendList;
|
const std::list<Type::FriendInfo>& friendList = scope->definedType->friendList;
|
||||||
for (std::list<Type::FriendInfo>::const_iterator it = friendList.begin(); !used && it != friendList.end(); ++it) {
|
for (std::list<Type::FriendInfo>::const_iterator it = friendList.begin(); !used && it != friendList.end(); ++it) {
|
||||||
if (it->type)
|
if (it->type)
|
||||||
used = checkFunctionUsage(funcName, it->type->classScope);
|
used = checkFunctionUsage(privateFuncs.front(), it->type->classScope);
|
||||||
else
|
else
|
||||||
used = true; // Assume, it is used if we do not see friend class
|
used = true; // Assume, it is used if we do not see friend class
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!used)
|
if (!used)
|
||||||
unusedPrivateFunctionError(privateFuncs.front()->tokenDef, scope->className, funcName);
|
unusedPrivateFunctionError(privateFuncs.front()->tokenDef, scope->className, privateFuncs.front()->name());
|
||||||
|
|
||||||
privateFuncs.pop_front();
|
privateFuncs.pop_front();
|
||||||
}
|
}
|
||||||
|
|
|
@ -374,16 +374,16 @@ std::string MathLib::normalizeCharacterLiteral(const std::string& iLiteral)
|
||||||
switch (iLiteral[idx]) {
|
switch (iLiteral[idx]) {
|
||||||
case 'x':
|
case 'x':
|
||||||
// Hexa-decimal number: skip \x and interpret the next two characters
|
// Hexa-decimal number: skip \x and interpret the next two characters
|
||||||
{
|
{
|
||||||
if (++idx == iLiteralLen)
|
if (++idx == iLiteralLen)
|
||||||
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant '" + iLiteral + "'.");
|
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant '" + iLiteral + "'.");
|
||||||
std::string tempBuf;
|
std::string tempBuf;
|
||||||
|
tempBuf.push_back(iLiteral[idx]);
|
||||||
|
if (++idx != iLiteralLen)
|
||||||
tempBuf.push_back(iLiteral[idx]);
|
tempBuf.push_back(iLiteral[idx]);
|
||||||
if (++idx != iLiteralLen)
|
normalizedLiteral.push_back(static_cast<char>(MathLib::toULongNumber("0x" + tempBuf)));
|
||||||
tempBuf.push_back(iLiteral[idx]);
|
continue;
|
||||||
normalizedLiteral.push_back(static_cast<char>(MathLib::toULongNumber("0x" + tempBuf)));
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'U':
|
case 'U':
|
||||||
// Unicode string; just skip the \u or \U
|
// Unicode string; just skip the \u or \U
|
||||||
|
|
|
@ -408,7 +408,7 @@ private:
|
||||||
" void f() { }\n"
|
" void f() { }\n"
|
||||||
" void f(int) { }\n"
|
" void f(int) { }\n"
|
||||||
"};");
|
"};");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("[test.cpp:10]: (style) Unused private function: 'A::f'\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void incompleteImplementation() {
|
void incompleteImplementation() {
|
||||||
|
|
Loading…
Reference in New Issue