Refactoring: Better distinguish between C and C++ in a few checks.
This commit is contained in:
parent
56e90f95d9
commit
4a47b8b3ae
|
@ -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()) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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%")) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(...)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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..
|
||||||
|
|
Loading…
Reference in New Issue