#6269 false positives in case of overloaded standard library functions. Detect memset() with proper argument cound, using new function numberOfArguments()

This commit is contained in:
Alexander Mai 2015-12-06 12:50:05 +01:00
parent 98f2cd021e
commit 9d8dffbd79
7 changed files with 42 additions and 21 deletions

View File

@ -302,3 +302,17 @@ bool isVariableChanged(const Token *start, const Token *end, const unsigned int
}
return false;
}
int numberOfArguments(const Token *start)
{
int arguments=0;
const Token* const openBracket = start->next();
if (openBracket && openBracket->str()=="(" && openBracket->next() && openBracket->next()->str()!=")") {
const Token* argument=openBracket->next();
while (argument) {
++arguments;
argument = argument->nextArgument();
}
}
return arguments;
}

View File

@ -67,4 +67,10 @@ bool isWithoutSideEffects(bool cpp, const Token* tok);
/** Is variable changed in block of code? */
bool isVariableChanged(const Token *start, const Token *end, const unsigned int varid);
/** Determines the number of arguments - if token is a function call or macro
* @param start token which is supposed to be the function/macro name.
* \return Number of arguments
*/
int numberOfArguments(const Token *start);
#endif // astutilsH

View File

@ -1076,7 +1076,7 @@ void CheckOther::checkMemsetZeroBytes()
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::simpleMatch(tok, "memset (")) {
if (Token::simpleMatch(tok, "memset (") && (numberOfArguments(tok)==3)) {
const Token* lastParamTok = tok->next()->link()->previous();
if (lastParamTok->str() == "0")
memsetZeroBytesError(tok, tok->strAt(2));

View File

@ -869,15 +869,7 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
if (ftok->varId())
return true;
int callargs = 0;
for (const Token *tok = ftok->tokAt(2); tok && tok->str() != ")"; tok = tok->next()) {
if (callargs == 0)
callargs = 1;
if (tok->str() == ",")
callargs++;
else if (tok->link() && Token::Match(tok, "<|(|["))
tok = tok->link();
}
int callargs = numberOfArguments(ftok);
const std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it = argumentChecks.find(functionName(ftok));
if (it == argumentChecks.end())
return (callargs != 0);

View File

@ -1432,8 +1432,7 @@ void SymbolDatabase::validate() const
const Scope* scope = functionScopes[i];
const Function* function = scope->function;
if (scope->isExecutable() && !function) {
if (_settings->debugwarnings)
{
if (_settings->debugwarnings) {
const std::list<const Token*> callstack(1, scope->classDef);
const std::string msg = std::string("executable scope '") + scope->classDef->str() + "' with unknown function";
const ErrorLogger::ErrorMessage errmsg(callstack, &_tokenizer->list, Severity::debug,

View File

@ -758,9 +758,9 @@ Token* Token::nextArgument() const
else if (tok->link() && Token::Match(tok, "(|{|[|<"))
tok = tok->link();
else if (Token::Match(tok, ")|;"))
return 0;
return nullptr;
}
return 0;
return nullptr;
}
Token* Token::nextArgumentBeforeCreateLinks2() const
@ -775,9 +775,9 @@ Token* Token::nextArgumentBeforeCreateLinks2() const
if (temp)
tok = temp;
} else if (Token::Match(tok, ")|;"))
return 0;
return nullptr;
}
return 0;
return nullptr;
}
Token* Token::nextTemplateArgument() const
@ -788,9 +788,9 @@ Token* Token::nextTemplateArgument() const
else if (tok->link() && Token::Match(tok, "(|{|[|<"))
tok = tok->link();
else if (Token::Match(tok, ">|;"))
return 0;
return nullptr;
}
return 0;
return nullptr;
}
const Token * Token::findClosingBracket() const
@ -846,7 +846,7 @@ const Token *Token::findsimplematch(const Token *startTok, const char pattern[],
if (Token::simpleMatch(tok, pattern))
return tok;
}
return 0;
return nullptr;
}
const Token *Token::findmatch(const Token *startTok, const char pattern[], unsigned int varId)
@ -855,7 +855,7 @@ const Token *Token::findmatch(const Token *startTok, const char pattern[], unsig
if (Token::Match(tok, pattern, varId))
return tok;
}
return 0;
return nullptr;
}
const Token *Token::findmatch(const Token *startTok, const char pattern[], const Token *end, unsigned int varId)
@ -864,7 +864,7 @@ const Token *Token::findmatch(const Token *startTok, const char pattern[], const
if (Token::Match(tok, pattern, varId))
return tok;
}
return 0;
return nullptr;
}
void Token::insertToken(const std::string &tokenStr, bool prepend)

View File

@ -3275,6 +3275,16 @@ private:
" memset(p, sizeof(p), i);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
// #6269 false positives in case of overloaded standard library functions
check("class c {\n"
" void memset( int i );\n"
" void f( void ) {\n"
" memset( 0 );\n"
" }\n"
"};");
ASSERT_EQUALS("", errout.str());
}
void memsetInvalid2ndParam() {