Refactoring: Better distinguish between C and C++ in a few checks.

This commit is contained in:
amai2012 2015-06-28 16:49:16 +02:00
parent 56e90f95d9
commit 4a47b8b3ae
11 changed files with 31 additions and 33 deletions

View File

@ -158,7 +158,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
// Deallocation and then dereferencing pointer.. // Deallocation and then dereferencing pointer..
if (tok->varId() > 0) { if (tok->varId() > 0) {
const std::map<unsigned int, VarInfo::AllocInfo>::iterator var = alloctype.find(tok->varId()); const std::map<unsigned int, VarInfo::AllocInfo>::const_iterator var = alloctype.find(tok->varId());
if (var != alloctype.end()) { if (var != alloctype.end()) {
if (var->second.status == VarInfo::DEALLOC && (!Token::Match(tok, "%name% =") || tok->strAt(-1) == "*")) { if (var->second.status == VarInfo::DEALLOC && (!Token::Match(tok, "%name% =") || tok->strAt(-1) == "*")) {
deallocUseError(tok, tok->str()); deallocUseError(tok, tok->str());
@ -373,7 +373,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
} }
// throw // throw
else if (tok->str() == "throw") { else if (_tokenizer->isCPP() && tok->str() == "throw") {
bool tryFound = false; bool tryFound = false;
const Scope* scope = tok->scope(); const Scope* scope = tok->scope();
while (scope && scope->isExecutable()) { while (scope && scope->isExecutable()) {

View File

@ -1379,6 +1379,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
void CheckMemoryLeakInFunction::simplifycode(Token *tok) const void CheckMemoryLeakInFunction::simplifycode(Token *tok) const
{ {
if (_tokenizer->isCPP())
{ {
// Replace "throw" that is not in a try block with "return" // Replace "throw" that is not in a try block with "return"
int indentlevel = 0; int indentlevel = 0;

View File

@ -57,7 +57,7 @@ void CheckNonReentrantFunctions::nonReentrantFunctions()
continue; continue;
// Check for "std" or global namespace, ignore other namespaces // Check for "std" or global namespace, ignore other namespaces
if (prev->str() == "::" && prev->previous() && prev->previous()->str() != "std" && prev->previous()->isName()) if (_tokenizer->isCPP() && prev->str() == "::" && prev->previous() && prev->previous()->str() != "std" && prev->previous()->isName())
continue; continue;
} }

View File

@ -1736,7 +1736,7 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, Alloc al
if (Token::Match(vartok->previous(), "[(,] %name% [,)]") || Token::Match(vartok->tokAt(-2), "[(,] & %name% [,)]")) { if (Token::Match(vartok->previous(), "[(,] %name% [,)]") || Token::Match(vartok->tokAt(-2), "[(,] & %name% [,)]")) {
const int use = isFunctionParUsage(vartok, pointer, alloc); const int use = isFunctionParUsage(vartok, pointer, alloc);
if (use >= 0) if (use >= 0)
return use; return (use>0);
} }
if (Token::Match(vartok->previous(), "++|--|%cop%")) { if (Token::Match(vartok->previous(), "++|--|%cop%")) {

View File

@ -51,7 +51,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi
continue; continue;
// Don't care about templates // Don't care about templates
if (func->retDef->str() == "template") if (tokenizer.isCPP() && func->retDef->str() == "template")
continue; continue;
FunctionUsage &usage = _functions[func->name()]; FunctionUsage &usage = _functions[func->name()];
@ -216,8 +216,7 @@ void CheckUnusedFunctions::check(ErrorLogger * const errorLogger)
if (func.usedOtherFile || func.filename.empty()) if (func.usedOtherFile || func.filename.empty())
continue; continue;
if (it->first == "main" || if (it->first == "main" ||
it->first == "WinMain" || (_settings->isWindowsPlatform() && (it->first == "WinMain" || it->first == "_tmain")) ||
it->first == "_tmain" ||
it->first == "if" || it->first == "if" ||
(it->first.compare(0, 8, "operator") == 0 && it->first.size() > 8 && !std::isalnum(it->first[8]))) (it->first.compare(0, 8, "operator") == 0 && it->first.size() > 8 && !std::isalnum(it->first[8])))
continue; continue;

View File

@ -659,7 +659,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
const Token* scopeBegin = argStart->link()->next(); const Token* scopeBegin = argStart->link()->next();
if (scopeBegin->isName()) { // Jump behind 'const' or unknown Macro if (scopeBegin->isName()) { // Jump behind 'const' or unknown Macro
scopeBegin = scopeBegin->next(); scopeBegin = scopeBegin->next();
if (scopeBegin->str() == "throw") if (_tokenizer->isCPP() && scopeBegin->str() == "throw")
scopeBegin = scopeBegin->next(); scopeBegin = scopeBegin->next();
if (scopeBegin->link() && scopeBegin->str() == "(") // Jump behind unknown macro of type THROW(...) if (scopeBegin->link() && scopeBegin->str() == "(") // Jump behind unknown macro of type THROW(...)

View File

@ -2243,19 +2243,19 @@ static Token *skipTernaryOp(Token *tok)
return tok; return tok;
} }
Token * Tokenizer::startOfFunction(Token * tok) Token * Tokenizer::startOfFunction(Token * tok) const
{ {
if (tok && tok->str() == ")") { if (tok && tok->str() == ")") {
tok = tok->next(); tok = tok->next();
while (tok && tok->str() != "{") { while (tok && tok->str() != "{") {
if (Token::Match(tok, "const|volatile")) { if (isCPP() && Token::Match(tok, "const|volatile")) {
tok = tok->next(); tok = tok->next();
} else if (tok->str() == "noexcept") { } else if (isCPP() && tok->str() == "noexcept") {
tok = tok->next(); tok = tok->next();
if (tok && tok->str() == "(") { if (tok && tok->str() == "(") {
tok = tok->link()->next(); tok = tok->link()->next();
} }
} else if (tok->str() == "throw" && tok->next() && tok->next()->str() == "(") { } else if (isCPP() && tok->str() == "throw" && tok->next() && tok->next()->str() == "(") {
tok = tok->next()->link()->next(); tok = tok->next()->link()->next();
} }
// unknown macros ") MACRO {" and ") MACRO(...) {" // unknown macros ") MACRO {" and ") MACRO(...) {"
@ -4217,7 +4217,7 @@ void Tokenizer::simplifyFlowControl()
} else if (Token::Match(tok,"return|goto") || } else if (Token::Match(tok,"return|goto") ||
(Token::Match(tok->previous(), "[;{}] %name% (") && (Token::Match(tok->previous(), "[;{}] %name% (") &&
_settings->library.isnoreturn(tok)) || _settings->library.isnoreturn(tok)) ||
(tok->str() == "throw" && !isC())) { (isCPP() && tok->str() == "throw")) {
//TODO: ensure that we exclude user-defined 'exit|abort|throw', except for 'noreturn' //TODO: ensure that we exclude user-defined 'exit|abort|throw', except for 'noreturn'
//catch the first ';' //catch the first ';'
for (Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) { for (Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
@ -9859,9 +9859,7 @@ namespace {
void Tokenizer::simplifyMicrosoftStringFunctions() void Tokenizer::simplifyMicrosoftStringFunctions()
{ {
// skip if not Windows // skip if not Windows
if (_settings->platformType != Settings::Win32A && if (!_settings->isWindowsPlatform())
_settings->platformType != Settings::Win32W &&
_settings->platformType != Settings::Win64)
return; return;
const bool ansi = _settings->platformType == Settings::Win32A; const bool ansi = _settings->platformType == Settings::Win32A;
@ -9894,9 +9892,7 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
void Tokenizer::simplifyBorland() void Tokenizer::simplifyBorland()
{ {
// skip if not Windows // skip if not Windows
if (_settings->platformType != Settings::Win32A && if (!_settings->isWindowsPlatform())
_settings->platformType != Settings::Win32W &&
_settings->platformType != Settings::Win64)
return; return;
if (isC()) if (isC())
return; return;
@ -9914,7 +9910,6 @@ void Tokenizer::simplifyBorland()
if (!tok) if (!tok)
break; break;
} }
else if (Token::Match(tok, "class %name% :|{")) { else if (Token::Match(tok, "class %name% :|{")) {
while (tok && tok->str() != "{" && tok->str() != ";") while (tok && tok->str() != "{" && tok->str() != ";")
tok = tok->next(); tok = tok->next();

View File

@ -840,7 +840,7 @@ private:
/** Disable assignment operator, no implementation */ /** Disable assignment operator, no implementation */
Tokenizer &operator=(const Tokenizer &); Tokenizer &operator=(const Tokenizer &);
static Token * startOfFunction(Token * tok); Token * startOfFunction(Token * tok) const;
static Token * startOfExecutableScope(Token * tok) { static Token * startOfExecutableScope(Token * tok) {
return const_cast<Token*>(startOfExecutableScope(const_cast<const Token *>(tok))); return const_cast<Token*>(startOfExecutableScope(const_cast<const Token *>(tok)));
} }

View File

@ -997,7 +997,7 @@ private:
" throw 1;\n" " throw 1;\n"
" }\n" " }\n"
" free(p);\n" " free(p);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(char *p, int x) {\n" check("void f(char *p, int x) {\n"
@ -1006,7 +1006,7 @@ private:
" throw 1;\n" " throw 1;\n"
" }\n" " }\n"
" delete p;\n" " delete p;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(char *p, int x) {\n" check("void f(char *p, int x) {\n"
@ -1015,7 +1015,7 @@ private:
" throw 1;\n" " throw 1;\n"
" }\n" " }\n"
" delete [] p;\n" " delete [] p;\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1063,8 +1063,8 @@ private:
check("void f() {\n" check("void f() {\n"
" char *p = malloc(10);\n" " char *p = malloc(10);\n"
" throw 123;\n" " throw 123;\n"
"}"); "}", true);
ASSERT_EQUALS("[test.c:3]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: p\n", errout.str());
check("void f() {\n" check("void f() {\n"
" char *p;\n" " char *p;\n"
@ -1073,7 +1073,7 @@ private:
" throw 123;\n" " throw 123;\n"
" } catch (...) { }\n" " } catch (...) { }\n"
" free(p);\n" " free(p);\n"
"}"); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -1155,7 +1155,7 @@ private:
" double *new = malloc(1*sizeof(double));\n" " double *new = malloc(1*sizeof(double));\n"
" free(new);\n" " free(new);\n"
" return 0;\n" " return 0;\n"
"}"); "}", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
}; };

View File

@ -672,7 +672,8 @@ private:
} }
} }
CheckMemoryLeakInFunction checkMemoryLeak(nullptr, &settings, this); Tokenizer tokenizer;
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, this);
checkMemoryLeak.simplifycode(tokens); checkMemoryLeak.simplifycode(tokens);
return list.front()->stringifyList(0, false); return list.front()->stringifyList(0, false);

View File

@ -333,7 +333,9 @@ private:
} }
void multipleFiles() { void multipleFiles() {
CheckUnusedFunctions c; Settings settings;
Tokenizer tokenizer(&settings, this);
CheckUnusedFunctions c(&tokenizer, &settings, nullptr);
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
@ -349,11 +351,11 @@ private:
Settings settings; Settings settings;
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer2(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.tokenize(istr, fname.str().c_str()); tokenizer2.tokenize(istr, fname.str().c_str());
c.parseTokens(tokenizer, "someFile.c", &settings); c.parseTokens(tokenizer2, "someFile.c", &settings);
} }
// Check for unused functions.. // Check for unused functions..