From 90bc59e0fa7b3fbdfea68ad9bfc9188fe57abdd5 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Mon, 28 Jul 2014 09:16:35 +0200 Subject: [PATCH] Fixed #6009 (Detect type mismatch in printf-like function when type is returned) --- lib/checkio.cpp | 12 ++++++------ test/testio.cpp | 9 +++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index add5c35da..e28bf18d2 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -1013,7 +1013,7 @@ void CheckIO::checkWrongPrintfScanfArguments() while (!done) { switch (*i) { case 's': - if (argInfo.variableInfo && argListTok->type() != Token::eString && + if (argListTok->type() != Token::eString && argInfo.isKnownType() && !argInfo.isArrayOrPointer()) { if (!Token::Match(argInfo.typeToken, "char|wchar_t")) { if (!(!argInfo.isArrayOrPointer() && argInfo.element)) @@ -1023,7 +1023,7 @@ void CheckIO::checkWrongPrintfScanfArguments() done = true; break; case 'n': - if ((argInfo.variableInfo && argInfo.isKnownType() && (!argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")) || argListTok->type() == Token::eString) + if ((argInfo.isKnownType() && (!argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")) || argListTok->type() == Token::eString) invalidPrintfArgTypeError_n(tok, numFormat, &argInfo); done = true; break; @@ -1362,7 +1362,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings) Token::Match(tok->linkAt(1)->linkAt(1), ") ,|)"))) { if (Token::Match(tok, "static_cast|reinterpret_cast|const_cast")) { typeToken = tok->tokAt(2); - if (typeToken->str() == "const") + while (typeToken->str() == "const" || typeToken->str() == "extern") typeToken = typeToken->next(); return; } @@ -1384,7 +1384,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings) const Function * function = varTok->link()->previous()->function(); if (function && function->retDef) { typeToken = function->retDef; - if (typeToken->str() == "const") + while (typeToken->str() == "const" || typeToken->str() == "extern") typeToken = typeToken->next(); functionInfo = function; element = true; @@ -1396,7 +1396,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings) const Function * function = tok1->linkAt(-1)->previous()->function(); if (function && function->retDef) { typeToken = function->retDef; - if (typeToken->str() == "const") + while (typeToken->str() == "const" || typeToken->str() == "extern") typeToken = typeToken->next(); functionInfo = function; element = false; @@ -1620,7 +1620,7 @@ bool CheckIO::ArgumentInfo::isKnownType() const if (variableInfo) return (typeToken->isStandardType() || typeToken->next()->isStandardType() || isComplexType()); else if (functionInfo) - return (typeToken->isStandardType() || functionInfo->retType); + return (typeToken->isStandardType() || functionInfo->retType || Token::Match(typeToken, "std :: string|wstring")); return typeToken->isStandardType() || Token::Match(typeToken, "std :: string|wstring"); } diff --git a/test/testio.cpp b/test/testio.cpp index 53b6cc935..9348bff41 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -3079,6 +3079,15 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); + // #6009 + check("extern std::string StringByReturnValue();\n" + "extern int IntByReturnValue();\n" + "void MyFunction() {\n" + " printf( \"%s - %s\", StringByReturnValue(), IntByReturnValue() );\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (warning) %s in format string (no. 1) requires 'char *' but the argument type is 'std::string'.\n" + "[test.cpp:4]: (warning) %s in format string (no. 2) requires 'char *' but the argument type is 'int'.\n", errout.str()); + } void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings