Skip to content

Commit 9d8dffb

Browse files
committed
danmar#6269 false positives in case of overloaded standard library functions. Detect memset() with proper argument cound, using new function numberOfArguments()
1 parent 98f2cd0 commit 9d8dffb

7 files changed

Lines changed: 42 additions & 21 deletions

File tree

lib/astutils.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,17 @@ bool isVariableChanged(const Token *start, const Token *end, const unsigned int
302302
}
303303
return false;
304304
}
305+
306+
int numberOfArguments(const Token *start)
307+
{
308+
int arguments=0;
309+
const Token* const openBracket = start->next();
310+
if (openBracket && openBracket->str()=="(" && openBracket->next() && openBracket->next()->str()!=")") {
311+
const Token* argument=openBracket->next();
312+
while (argument) {
313+
++arguments;
314+
argument = argument->nextArgument();
315+
}
316+
}
317+
return arguments;
318+
}

lib/astutils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,10 @@ bool isWithoutSideEffects(bool cpp, const Token* tok);
6767
/** Is variable changed in block of code? */
6868
bool isVariableChanged(const Token *start, const Token *end, const unsigned int varid);
6969

70+
/** Determines the number of arguments - if token is a function call or macro
71+
* @param start token which is supposed to be the function/macro name.
72+
* \return Number of arguments
73+
*/
74+
int numberOfArguments(const Token *start);
75+
7076
#endif // astutilsH

lib/checkother.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ void CheckOther::checkMemsetZeroBytes()
10761076
for (std::size_t i = 0; i < functions; ++i) {
10771077
const Scope * scope = symbolDatabase->functionScopes[i];
10781078
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
1079-
if (Token::simpleMatch(tok, "memset (")) {
1079+
if (Token::simpleMatch(tok, "memset (") && (numberOfArguments(tok)==3)) {
10801080
const Token* lastParamTok = tok->next()->link()->previous();
10811081
if (lastParamTok->str() == "0")
10821082
memsetZeroBytesError(tok, tok->strAt(2));

lib/library.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -869,15 +869,7 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
869869
if (ftok->varId())
870870
return true;
871871

872-
int callargs = 0;
873-
for (const Token *tok = ftok->tokAt(2); tok && tok->str() != ")"; tok = tok->next()) {
874-
if (callargs == 0)
875-
callargs = 1;
876-
if (tok->str() == ",")
877-
callargs++;
878-
else if (tok->link() && Token::Match(tok, "<|(|["))
879-
tok = tok->link();
880-
}
872+
int callargs = numberOfArguments(ftok);
881873
const std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it = argumentChecks.find(functionName(ftok));
882874
if (it == argumentChecks.end())
883875
return (callargs != 0);

lib/symboldatabase.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,8 +1432,7 @@ void SymbolDatabase::validate() const
14321432
const Scope* scope = functionScopes[i];
14331433
const Function* function = scope->function;
14341434
if (scope->isExecutable() && !function) {
1435-
if (_settings->debugwarnings)
1436-
{
1435+
if (_settings->debugwarnings) {
14371436
const std::list<const Token*> callstack(1, scope->classDef);
14381437
const std::string msg = std::string("executable scope '") + scope->classDef->str() + "' with unknown function";
14391438
const ErrorLogger::ErrorMessage errmsg(callstack, &_tokenizer->list, Severity::debug,

lib/token.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -758,9 +758,9 @@ Token* Token::nextArgument() const
758758
else if (tok->link() && Token::Match(tok, "(|{|[|<"))
759759
tok = tok->link();
760760
else if (Token::Match(tok, ")|;"))
761-
return 0;
761+
return nullptr;
762762
}
763-
return 0;
763+
return nullptr;
764764
}
765765

766766
Token* Token::nextArgumentBeforeCreateLinks2() const
@@ -775,9 +775,9 @@ Token* Token::nextArgumentBeforeCreateLinks2() const
775775
if (temp)
776776
tok = temp;
777777
} else if (Token::Match(tok, ")|;"))
778-
return 0;
778+
return nullptr;
779779
}
780-
return 0;
780+
return nullptr;
781781
}
782782

783783
Token* Token::nextTemplateArgument() const
@@ -788,9 +788,9 @@ Token* Token::nextTemplateArgument() const
788788
else if (tok->link() && Token::Match(tok, "(|{|[|<"))
789789
tok = tok->link();
790790
else if (Token::Match(tok, ">|;"))
791-
return 0;
791+
return nullptr;
792792
}
793-
return 0;
793+
return nullptr;
794794
}
795795

796796
const Token * Token::findClosingBracket() const
@@ -846,7 +846,7 @@ const Token *Token::findsimplematch(const Token *startTok, const char pattern[],
846846
if (Token::simpleMatch(tok, pattern))
847847
return tok;
848848
}
849-
return 0;
849+
return nullptr;
850850
}
851851

852852
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
855855
if (Token::Match(tok, pattern, varId))
856856
return tok;
857857
}
858-
return 0;
858+
return nullptr;
859859
}
860860

861861
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
864864
if (Token::Match(tok, pattern, varId))
865865
return tok;
866866
}
867-
return 0;
867+
return nullptr;
868868
}
869869

870870
void Token::insertToken(const std::string &tokenStr, bool prepend)

test/testother.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3275,6 +3275,16 @@ class TestOther : public TestFixture {
32753275
" memset(p, sizeof(p), i);\n"
32763276
"}\n");
32773277
ASSERT_EQUALS("", errout.str());
3278+
3279+
// #6269 false positives in case of overloaded standard library functions
3280+
check("class c {\n"
3281+
" void memset( int i );\n"
3282+
" void f( void ) {\n"
3283+
" memset( 0 );\n"
3284+
" }\n"
3285+
"};");
3286+
ASSERT_EQUALS("", errout.str());
3287+
32783288
}
32793289

32803290
void memsetInvalid2ndParam() {

0 commit comments

Comments
 (0)