Fixed #4964 (printf format argument check only supports simple variables)
This commit is contained in:
parent
bf8a786265
commit
707dfb4eea
|
@ -555,9 +555,10 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
}
|
||||
|
||||
// Perform type checks
|
||||
if (argListTok && Token::Match(argListTok->next(), "[,)]")) { // We can currently only check the type of arguments matching this simple pattern.
|
||||
const Variable *variableInfo = argListTok->variable();
|
||||
const Token* varTypeTok = variableInfo ? variableInfo->typeStartToken() : NULL;
|
||||
const Variable *variableInfo;
|
||||
const Token *varTypeTok;
|
||||
|
||||
if (getArgumentInfo(argListTok, &variableInfo, &varTypeTok)) {
|
||||
if (varTypeTok && varTypeTok->str() == "static")
|
||||
varTypeTok = varTypeTok->next();
|
||||
|
||||
|
@ -735,6 +736,33 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
}
|
||||
}
|
||||
|
||||
// We can currently only check the type of arguments matching these simple patterns:
|
||||
// var
|
||||
// var.var
|
||||
// var[...]
|
||||
//
|
||||
/// @todo add more complex variables, lietrals, functions, and generic expressions
|
||||
|
||||
bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Token **typeTok) const
|
||||
{
|
||||
if (tok && (Token::Match(tok->next(), "[,)]") ||
|
||||
Token::Match(tok->next(), ". %var% [,)]") ||
|
||||
(Token::simpleMatch(tok->next(), "[") && Token::Match(tok->linkAt(1)->next(), "[,)]")))) {
|
||||
if (tok->next()->str() == ".")
|
||||
tok = tok->tokAt(2);
|
||||
|
||||
const Variable *variableInfo = tok->variable();
|
||||
const Token *varTypeTok = variableInfo ? variableInfo->typeStartToken() : NULL;
|
||||
|
||||
*var = variableInfo;
|
||||
*typeTok = varTypeTok;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok,
|
||||
const std::string &functionName,
|
||||
unsigned int numFormat,
|
||||
|
|
|
@ -70,6 +70,8 @@ public:
|
|||
void checkWrongPrintfScanfArguments();
|
||||
|
||||
private:
|
||||
bool getArgumentInfo(const Token *tok, const Variable **var, const Token **typeTok) const;
|
||||
|
||||
// Reporting errors..
|
||||
void coutCerrMisusageError(const Token* tok, const std::string& streamName);
|
||||
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
|
||||
|
|
|
@ -793,6 +793,17 @@ private:
|
|||
"[test.cpp:5]: (warning) %llu in format string (no. 1) requires an unsigned long long integer given in the argument list.\n"
|
||||
"[test.cpp:6]: (warning) %lx in format string (no. 1) requires a long integer given in the argument list.\n"
|
||||
"[test.cpp:7]: (warning) %llx in format string (no. 1) requires a long long integer given in the argument list.\n", errout.str());
|
||||
|
||||
check("class Foo {\n"
|
||||
" double d;\n"
|
||||
"};\n"
|
||||
"int a[10];\n"
|
||||
"void foo(const Foo* foo) {\n"
|
||||
" printf(\"%d\", foo->d);\n"
|
||||
" printf(\"%f\", a[0]);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (warning) %d in format string (no. 1) requires a signed integer given in the argument list.\n"
|
||||
"[test.cpp:7]: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.\n", errout.str());
|
||||
}
|
||||
|
||||
void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings
|
||||
|
|
Loading…
Reference in New Issue