varFuncNullUB: fixed false positive when non-variadic argument is NULL (#4482)
This commit is contained in:
parent
723d95597b
commit
d46789ee4a
|
@ -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), ". . ."))
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue