#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:
parent
98f2cd021e
commit
9d8dffbd79
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue