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..
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->second.status == VarInfo::DEALLOC && (!Token::Match(tok, "%name% =") || tok->strAt(-1) == "*")) {
deallocUseError(tok, tok->str());
@ -373,7 +373,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
}
// throw
else if (tok->str() == "throw") {
else if (_tokenizer->isCPP() && tok->str() == "throw") {
bool tryFound = false;
const Scope* scope = tok->scope();
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
{
if (_tokenizer->isCPP())
{
// Replace "throw" that is not in a try block with "return"
int indentlevel = 0;

View File

@ -57,7 +57,7 @@ void CheckNonReentrantFunctions::nonReentrantFunctions()
continue;
// 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;
}

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% [,)]")) {
const int use = isFunctionParUsage(vartok, pointer, alloc);
if (use >= 0)
return use;
return (use>0);
}
if (Token::Match(vartok->previous(), "++|--|%cop%")) {

View File

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

View File

@ -659,7 +659,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
const Token* scopeBegin = argStart->link()->next();
if (scopeBegin->isName()) { // Jump behind 'const' or unknown Macro
scopeBegin = scopeBegin->next();
if (scopeBegin->str() == "throw")
if (_tokenizer->isCPP() && scopeBegin->str() == "throw")
scopeBegin = scopeBegin->next();
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;
}
Token * Tokenizer::startOfFunction(Token * tok)
Token * Tokenizer::startOfFunction(Token * tok) const
{
if (tok && tok->str() == ")") {
tok = tok->next();
while (tok && tok->str() != "{") {
if (Token::Match(tok, "const|volatile")) {
if (isCPP() && Token::Match(tok, "const|volatile")) {
tok = tok->next();
} else if (tok->str() == "noexcept") {
} else if (isCPP() && tok->str() == "noexcept") {
tok = tok->next();
if (tok && tok->str() == "(") {
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();
}
// unknown macros ") MACRO {" and ") MACRO(...) {"
@ -4217,7 +4217,7 @@ void Tokenizer::simplifyFlowControl()
} else if (Token::Match(tok,"return|goto") ||
(Token::Match(tok->previous(), "[;{}] %name% (") &&
_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'
//catch the first ';'
for (Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
@ -9859,9 +9859,7 @@ namespace {
void Tokenizer::simplifyMicrosoftStringFunctions()
{
// skip if not Windows
if (_settings->platformType != Settings::Win32A &&
_settings->platformType != Settings::Win32W &&
_settings->platformType != Settings::Win64)
if (!_settings->isWindowsPlatform())
return;
const bool ansi = _settings->platformType == Settings::Win32A;
@ -9894,9 +9892,7 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
void Tokenizer::simplifyBorland()
{
// skip if not Windows
if (_settings->platformType != Settings::Win32A &&
_settings->platformType != Settings::Win32W &&
_settings->platformType != Settings::Win64)
if (!_settings->isWindowsPlatform())
return;
if (isC())
return;
@ -9914,7 +9910,6 @@ void Tokenizer::simplifyBorland()
if (!tok)
break;
}
else if (Token::Match(tok, "class %name% :|{")) {
while (tok && tok->str() != "{" && tok->str() != ";")
tok = tok->next();

View File

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

View File

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

View File

@ -333,7 +333,9 @@ private:
}
void multipleFiles() {
CheckUnusedFunctions c;
Settings settings;
Tokenizer tokenizer(&settings, this);
CheckUnusedFunctions c(&tokenizer, &settings, nullptr);
// Clear the error buffer..
errout.str("");
@ -349,11 +351,11 @@ private:
Settings settings;
Tokenizer tokenizer(&settings, this);
Tokenizer tokenizer2(&settings, this);
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..