Fixed #4984 (False positive: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.)
This commit is contained in:
parent
80093f0a40
commit
228f6b1a87
|
@ -558,8 +558,9 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
const Variable *variableInfo;
|
||||
const Token *varTypeTok;
|
||||
const Function *functionInfo;
|
||||
bool element;
|
||||
|
||||
if (getArgumentInfo(argListTok, &variableInfo, &varTypeTok, &functionInfo)) {
|
||||
if (getArgumentInfo(argListTok, &variableInfo, &varTypeTok, &functionInfo, element)) {
|
||||
if (varTypeTok && varTypeTok->str() == "static")
|
||||
varTypeTok = varTypeTok->next();
|
||||
|
||||
|
@ -664,7 +665,9 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
(specifier[0] == 'l' && (!varTypeTok->isLong() || varTypeTok->str() != "double")) ||
|
||||
(specifier[0] != 'l' && varTypeTok->isLong())))
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier);
|
||||
else if (variableInfo && varTypeTok && ((isKnownType(variableInfo, varTypeTok) && !Token::Match(varTypeTok, "float|double")) || variableInfo->isPointer() || variableInfo->isArray()))
|
||||
else if (variableInfo && varTypeTok && ((isKnownType(variableInfo, varTypeTok) && !Token::Match(varTypeTok, "float|double")) ||
|
||||
(!element && variableInfo->isArrayOrPointer()) ||
|
||||
(element && !variableInfo->isArrayOrPointer())))
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier);
|
||||
else if (argListTok->type() == Token::eString)
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier);
|
||||
|
@ -760,13 +763,14 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
// We currently only support string literals, variables, and functions.
|
||||
/// @todo add non-string literals, and generic expressions
|
||||
|
||||
bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Token **typeTok, const Function **func) const
|
||||
bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Token **typeTok, const Function **func, bool &element) const
|
||||
{
|
||||
if (tok) {
|
||||
if (tok->type() == Token::eString) {
|
||||
*var = 0;
|
||||
*typeTok = 0;
|
||||
*func = 0;
|
||||
element = false;
|
||||
return true;
|
||||
} else if (tok->type() == Token::eVariable || tok->type() == Token::eFunction || Token::Match(tok, "%type% ::")) {
|
||||
while (Token::Match(tok, "%type% ::"))
|
||||
|
@ -774,7 +778,8 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok
|
|||
if (!tok || !(tok->type() == Token::eVariable || tok->type() == Token::eFunction))
|
||||
return false;
|
||||
const Token *varTok = 0;
|
||||
for (const Token *tok1 = tok->next(); tok1; tok1 = tok1->next()) {
|
||||
const Token *tok1 = tok->next();
|
||||
for (; tok1; tok1 = tok1->next()) {
|
||||
if (tok1->str() == "," || tok1->str() == ")") {
|
||||
if (tok1->previous()->str() == "]")
|
||||
varTok = tok1->linkAt(-1)->previous();
|
||||
|
@ -784,6 +789,7 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok
|
|||
*var = 0;
|
||||
*typeTok = function->retDef;
|
||||
*func = function;
|
||||
element = false;
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
|
@ -802,6 +808,7 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok
|
|||
*var = variableInfo;
|
||||
*typeTok = variableInfo ? variableInfo->typeStartToken() : NULL;
|
||||
*func = 0;
|
||||
element = tok1->previous()->str() == "]";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
void checkWrongPrintfScanfArguments();
|
||||
|
||||
private:
|
||||
bool getArgumentInfo(const Token *tok, const Variable **var, const Token **typeTok, const Function **func) const;
|
||||
bool getArgumentInfo(const Token *tok, const Variable **var, const Token **typeTok, const Function **func, bool &element) const;
|
||||
|
||||
// Reporting errors..
|
||||
void coutCerrMisusageError(const Token* tok, const std::string& streamName);
|
||||
|
|
|
@ -334,6 +334,14 @@ public:
|
|||
return getFlag(fIsPointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array or pointer variable.
|
||||
* @return true if pointer or array, false otherwise
|
||||
*/
|
||||
bool isArrayOrPointer() const {
|
||||
return getFlag(fIsArray) || getFlag(fIsPointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is reference variable.
|
||||
* @return true if reference, false otherwise
|
||||
|
|
|
@ -1015,6 +1015,12 @@ private:
|
|||
"void foo() { printf(\"%d %ld %u %lu %f %lf\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// #4984
|
||||
check("void f(double *x) {\n"
|
||||
" printf(\"%f\", x[0]);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
}
|
||||
|
||||
void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings
|
||||
|
|
Loading…
Reference in New Issue