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 CWE762(762U);
|
||||
|
||||
static const char * getFunctionTypeName(
|
||||
Function::Type type)
|
||||
static const char * getFunctionTypeName(Function::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case Function::eConstructor:
|
||||
|
@ -873,7 +872,7 @@ void CheckClass::suggestInitializationList(const Token* tok, const std::string&
|
|||
// 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)
|
||||
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 (Token::Match(func->tokenDef, "%name% (")) {
|
||||
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;
|
||||
if (ftok->str() == "(")
|
||||
ftok = ftok->link();
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
} 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -910,7 +911,7 @@ static bool checkFunctionUsage(const std::string& name, const Scope* scope)
|
|||
if (tok)
|
||||
tok = tok->tokAt(2);
|
||||
while (tok && tok->str() != ";") {
|
||||
if (tok->str() == name && (tok->strAt(-1) == "." || tok->strAt(-2) == scope->className))
|
||||
if (tok->function() == privfunc)
|
||||
return true;
|
||||
tok = tok->next();
|
||||
}
|
||||
|
@ -952,20 +953,19 @@ void CheckClass::privateFunctions()
|
|||
}
|
||||
|
||||
while (!privateFuncs.empty()) {
|
||||
const std::string& funcName = privateFuncs.front()->tokenDef->str();
|
||||
// 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
|
||||
const std::list<Type::FriendInfo>& friendList = scope->definedType->friendList;
|
||||
for (std::list<Type::FriendInfo>::const_iterator it = friendList.begin(); !used && it != friendList.end(); ++it) {
|
||||
if (it->type)
|
||||
used = checkFunctionUsage(funcName, it->type->classScope);
|
||||
used = checkFunctionUsage(privateFuncs.front(), it->type->classScope);
|
||||
else
|
||||
used = true; // Assume, it is used if we do not see friend class
|
||||
}
|
||||
|
||||
if (!used)
|
||||
unusedPrivateFunctionError(privateFuncs.front()->tokenDef, scope->className, funcName);
|
||||
unusedPrivateFunctionError(privateFuncs.front()->tokenDef, scope->className, privateFuncs.front()->name());
|
||||
|
||||
privateFuncs.pop_front();
|
||||
}
|
||||
|
|
|
@ -374,16 +374,16 @@ std::string MathLib::normalizeCharacterLiteral(const std::string& iLiteral)
|
|||
switch (iLiteral[idx]) {
|
||||
case 'x':
|
||||
// Hexa-decimal number: skip \x and interpret the next two characters
|
||||
{
|
||||
if (++idx == iLiteralLen)
|
||||
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant '" + iLiteral + "'.");
|
||||
std::string tempBuf;
|
||||
{
|
||||
if (++idx == iLiteralLen)
|
||||
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant '" + iLiteral + "'.");
|
||||
std::string tempBuf;
|
||||
tempBuf.push_back(iLiteral[idx]);
|
||||
if (++idx != iLiteralLen)
|
||||
tempBuf.push_back(iLiteral[idx]);
|
||||
if (++idx != iLiteralLen)
|
||||
tempBuf.push_back(iLiteral[idx]);
|
||||
normalizedLiteral.push_back(static_cast<char>(MathLib::toULongNumber("0x" + tempBuf)));
|
||||
continue;
|
||||
}
|
||||
normalizedLiteral.push_back(static_cast<char>(MathLib::toULongNumber("0x" + tempBuf)));
|
||||
continue;
|
||||
}
|
||||
case 'u':
|
||||
case 'U':
|
||||
// Unicode string; just skip the \u or \U
|
||||
|
|
|
@ -408,7 +408,7 @@ private:
|
|||
" void f() { }\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() {
|
||||
|
|
Loading…
Reference in New Issue