varFuncNullUB: fixed false positive when non-variadic argument is NULL (#4482)

This commit is contained in:
Daniel Marjamäki 2013-01-14 06:44:52 +01:00
parent 723d95597b
commit d46789ee4a
3 changed files with 10 additions and 1 deletions

View File

@ -3764,16 +3764,19 @@ void CheckOther::checkVarFuncNullUB()
if (Token::Match(tok,"[(,] NULL [,)]")) { if (Token::Match(tok,"[(,] NULL [,)]")) {
// Locate function name in this function call. // Locate function name in this function call.
const Token *ftok = tok; const Token *ftok = tok;
int argnr = 1;
while (ftok && ftok->str() != "(") { while (ftok && ftok->str() != "(") {
if (ftok->str() == ")") if (ftok->str() == ")")
ftok = ftok->link(); ftok = ftok->link();
else if (ftok->str() == ",")
++argnr;
ftok = ftok->previous(); ftok = ftok->previous();
} }
ftok = ftok ? ftok->previous() : NULL; ftok = ftok ? ftok->previous() : NULL;
if (ftok && ftok->isName()) { if (ftok && ftok->isName()) {
// If this is a variadic function then report error // If this is a variadic function then report error
const Function *f = symbolDatabase->findFunctionByName(ftok->str(), scope); const Function *f = symbolDatabase->findFunctionByName(ftok->str(), scope);
if (f) { if (f && f->argCount() <= argnr) {
const Token *tok2 = f->argDef; const Token *tok2 = f->argDef;
tok2 = tok2 ? tok2->link() : NULL; // goto ')' tok2 = tok2 ? tok2->link() : NULL; // goto ')'
if (Token::simpleMatch(tok2->tokAt(-3), ". . .")) if (Token::simpleMatch(tok2->tokAt(-3), ". . ."))

View File

@ -6806,6 +6806,10 @@ private:
check("void a(...);\n" check("void a(...);\n"
"void b() { a(NULL); }"); "void b() { a(NULL); }");
ASSERT_EQUALS("[test.cpp:2]: (portability) Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (portability) Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n", errout.str());
check("void a(char *p, ...);\n"
"void b() { a(NULL, 2); }");
ASSERT_EQUALS("", errout.str());
} }
}; };

View File

@ -2086,6 +2086,8 @@ private:
} }
void macro_NULL() { void macro_NULL() {
// Let the tokenizer handle NULL.
// See ticket #4482 - UB when passing NULL to variadic function
ASSERT_EQUALS("\n$0", OurPreprocessor::expandMacros("#define null 0\nnull")); ASSERT_EQUALS("\n$0", OurPreprocessor::expandMacros("#define null 0\nnull"));
ASSERT_EQUALS("\nNULL", OurPreprocessor::expandMacros("#define NULL 0\nNULL")); ASSERT_EQUALS("\nNULL", OurPreprocessor::expandMacros("#define NULL 0\nNULL"));
} }