Fixed #6009 (Detect type mismatch in printf-like function when type is returned)
This commit is contained in:
parent
76020d2ad0
commit
90bc59e0fa
|
@ -1013,7 +1013,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
||||||
while (!done) {
|
while (!done) {
|
||||||
switch (*i) {
|
switch (*i) {
|
||||||
case 's':
|
case 's':
|
||||||
if (argInfo.variableInfo && argListTok->type() != Token::eString &&
|
if (argListTok->type() != Token::eString &&
|
||||||
argInfo.isKnownType() && !argInfo.isArrayOrPointer()) {
|
argInfo.isKnownType() && !argInfo.isArrayOrPointer()) {
|
||||||
if (!Token::Match(argInfo.typeToken, "char|wchar_t")) {
|
if (!Token::Match(argInfo.typeToken, "char|wchar_t")) {
|
||||||
if (!(!argInfo.isArrayOrPointer() && argInfo.element))
|
if (!(!argInfo.isArrayOrPointer() && argInfo.element))
|
||||||
|
@ -1023,7 +1023,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
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);
|
invalidPrintfArgTypeError_n(tok, numFormat, &argInfo);
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1362,7 +1362,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings)
|
||||||
Token::Match(tok->linkAt(1)->linkAt(1), ") ,|)"))) {
|
Token::Match(tok->linkAt(1)->linkAt(1), ") ,|)"))) {
|
||||||
if (Token::Match(tok, "static_cast|reinterpret_cast|const_cast")) {
|
if (Token::Match(tok, "static_cast|reinterpret_cast|const_cast")) {
|
||||||
typeToken = tok->tokAt(2);
|
typeToken = tok->tokAt(2);
|
||||||
if (typeToken->str() == "const")
|
while (typeToken->str() == "const" || typeToken->str() == "extern")
|
||||||
typeToken = typeToken->next();
|
typeToken = typeToken->next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1384,7 +1384,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings)
|
||||||
const Function * function = varTok->link()->previous()->function();
|
const Function * function = varTok->link()->previous()->function();
|
||||||
if (function && function->retDef) {
|
if (function && function->retDef) {
|
||||||
typeToken = function->retDef;
|
typeToken = function->retDef;
|
||||||
if (typeToken->str() == "const")
|
while (typeToken->str() == "const" || typeToken->str() == "extern")
|
||||||
typeToken = typeToken->next();
|
typeToken = typeToken->next();
|
||||||
functionInfo = function;
|
functionInfo = function;
|
||||||
element = true;
|
element = true;
|
||||||
|
@ -1396,7 +1396,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings)
|
||||||
const Function * function = tok1->linkAt(-1)->previous()->function();
|
const Function * function = tok1->linkAt(-1)->previous()->function();
|
||||||
if (function && function->retDef) {
|
if (function && function->retDef) {
|
||||||
typeToken = function->retDef;
|
typeToken = function->retDef;
|
||||||
if (typeToken->str() == "const")
|
while (typeToken->str() == "const" || typeToken->str() == "extern")
|
||||||
typeToken = typeToken->next();
|
typeToken = typeToken->next();
|
||||||
functionInfo = function;
|
functionInfo = function;
|
||||||
element = false;
|
element = false;
|
||||||
|
@ -1620,7 +1620,7 @@ bool CheckIO::ArgumentInfo::isKnownType() const
|
||||||
if (variableInfo)
|
if (variableInfo)
|
||||||
return (typeToken->isStandardType() || typeToken->next()->isStandardType() || isComplexType());
|
return (typeToken->isStandardType() || typeToken->next()->isStandardType() || isComplexType());
|
||||||
else if (functionInfo)
|
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");
|
return typeToken->isStandardType() || Token::Match(typeToken, "std :: string|wstring");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3079,6 +3079,15 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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
|
void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings
|
||||||
|
|
Loading…
Reference in New Issue