CheckIo: Revised patch that fixes bug in class function return type. Ticket: #4964

This commit is contained in:
Robert Reif 2013-08-24 22:34:52 +02:00 committed by Daniel Marjamäki
parent a70b0cd0f3
commit 26de3646e9
3 changed files with 36 additions and 9 deletions

View File

@ -647,7 +647,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
case 'p':
if (functionInfo && varTypeTok && varTypeTok->type() == Token::eType && varTypeTok->next()->str() != "*")
invalidPrintfArgTypeError_p(tok, numFormat);
else if (variableInfo && varTypeTok && isKnownType(variableInfo, varTypeTok) && !Token::Match(varTypeTok, "short|long|int|size_t") && !variableInfo->isPointer() && !variableInfo->isArray())
else if (variableInfo && varTypeTok && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray())
invalidPrintfArgTypeError_p(tok, numFormat);
else if (argListTok->type() == Token::eString)
invalidPrintfArgTypeError_p(tok, numFormat);
@ -758,7 +758,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
}
// We currently only support string literals, variables, and functions.
/// @todo add non-string literals, qualification, and generic expressions
/// @todo add non-string literals, and generic expressions
bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Token **typeTok, const Function **func) const
{
@ -768,7 +768,11 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok
*typeTok = 0;
*func = 0;
return true;
} else if (tok->type() == Token::eVariable || tok->type() == Token::eFunction) {
} else if (tok->type() == Token::eVariable || tok->type() == Token::eFunction || Token::Match(tok, "%type% ::")) {
while (Token::Match(tok, "%type% ::"))
tok = tok->tokAt(2);
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()) {
if (tok1->str() == "," || tok1->str() == ")") {

View File

@ -427,7 +427,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
tok1 = tok1->next();
if (tok1)
function.retDef = tok1->next();
function.retDef = tok1;
}
const Token *end;

View File

@ -919,12 +919,35 @@ private:
check("namespace bar { int f() { return 0; } }\n"
"void foo() { printf(\"%u %lu %f %lf %p\", bar::f(), bar::f(), bar::f(), bar::f(), bar::f()); }");
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n"
"[test.cpp:2]: (warning) %lu in format string (no. 2) requires an unsigned long integer given in the argument list.\n"
"[test.cpp:2]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %lf in format string (no. 4) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %p in format string (no. 5) requires an address given in the argument list.\n", "", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n"
"[test.cpp:2]: (warning) %lu in format string (no. 2) requires an unsigned long integer given in the argument list.\n"
"[test.cpp:2]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %lf in format string (no. 4) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %p in format string (no. 5) requires an address given in the argument list.\n", errout.str());
check("struct Fred { int i; } f;\n"
"void foo() { printf(\"%u %lu %f %lf %p\", f.i, f.i, f.i, f.i, f.i); }");
ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n"
"[test.cpp:2]: (warning) %lu in format string (no. 2) requires an unsigned long integer given in the argument list.\n"
"[test.cpp:2]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %lf in format string (no. 4) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %p in format string (no. 5) requires an address given in the argument list.\n", errout.str());
check("struct Fred { unsigned int u; } f;\n"
"void foo() { printf(\"%d %ld %f %lf %p\", f.u, f.u, f.u, f.u, f.u); }");
ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 1) requires a signed integer given in the argument list.\n"
"[test.cpp:2]: (warning) %ld in format string (no. 2) requires a signed long integer given in the argument list.\n"
"[test.cpp:2]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %lf in format string (no. 4) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %p in format string (no. 5) requires an address given in the argument list.\n", errout.str());
check("struct Fred { unsigned int ui() { return 0; } } f;\n"
"void foo() { printf(\"%d %ld %f %lf %p\", f.ui(), f.ui(), f.ui(), f.ui(), f.ui()); }");
ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 1) requires a signed integer given in the argument list.\n"
"[test.cpp:2]: (warning) %ld in format string (no. 2) requires a signed long integer given in the argument list.\n"
"[test.cpp:2]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %lf in format string (no. 4) requires a floating point number given in the argument list.\n"
"[test.cpp:2]: (warning) %p in format string (no. 5) requires an address given in the argument list.\n", errout.str());
}
void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings