From bce15b1aded35510502a4881990c929d997d5c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 16 May 2016 09:36:26 +0200 Subject: [PATCH] CheckClass: refactored the code, use symboldatabase instead of name comparisons when possible, fixed a FN. --- lib/checkclass.cpp | 22 +++++++++++----------- lib/mathlib.cpp | 18 +++++++++--------- test/testunusedprivfunc.cpp | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 44cc2a5d8..8298cdb75 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -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::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& friendList = scope->definedType->friendList; for (std::list::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(); } diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 4773b8c20..5a2007d25 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -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(MathLib::toULongNumber("0x" + tempBuf))); - continue; - } + normalizedLiteral.push_back(static_cast(MathLib::toULongNumber("0x" + tempBuf))); + continue; + } case 'u': case 'U': // Unicode string; just skip the \u or \U diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 85b1d0314..988ff3e19 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -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() {