diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 568ac2416..484498083 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -1024,7 +1024,7 @@ void CheckIO::checkWrongPrintfScanfArguments() break; } } - } else if (argInfo.isArrayOrPointer()) { + } else if (argInfo.isArrayOrPointer() && !argInfo.element) { // use %p on pointers and arrays invalidPrintfArgTypeError_int(tok, numFormat, specifier, &argInfo); } @@ -1083,7 +1083,7 @@ void CheckIO::checkWrongPrintfScanfArguments() break; } } - } else if (argInfo.isArrayOrPointer()) { + } else if (argInfo.isArrayOrPointer() && !argInfo.element) { // use %p on pointers and arrays invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo); } @@ -1141,7 +1141,7 @@ void CheckIO::checkWrongPrintfScanfArguments() break; } } - } else if (argInfo.isArrayOrPointer()) { + } else if (argInfo.isArrayOrPointer() && !argInfo.element) { invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo); } done = true; @@ -1171,7 +1171,7 @@ void CheckIO::checkWrongPrintfScanfArguments() (specifier[0] != 'L' && argInfo.typeToken->isLong())) invalidPrintfArgTypeError_float(tok, numFormat, specifier, &argInfo); - } else if (argInfo.isArrayOrPointer()) { + } else if (argInfo.isArrayOrPointer() && !argInfo.element) { // use %p on pointers and arrays invalidPrintfArgTypeError_float(tok, numFormat, specifier, &argInfo); } @@ -1717,7 +1717,7 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo) type = type->next(); } type->stringify(os, false, true); - if (type->strAt(1) == "*" && !(argInfo->functionInfo && argInfo->element)) + if (type->strAt(1) == "*" && !argInfo->element) os << " *"; else if (argInfo->variableInfo && !argInfo->element && argInfo->variableInfo->isArray()) os << " *"; diff --git a/test/testio.cpp b/test/testio.cpp index 0b8b915a8..199c3f1e1 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -2044,6 +2044,21 @@ private: ASSERT_EQUALS("[test.cpp:2]: (warning) %f in format string (no. 1) requires 'double' but the argument type is 'int'.\n" "[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const void *'.\n", errout.str()); + check("void foo() {\n" + " UNKNOWN * u;\n" + " printf(\"%d %x %u %f\", u[i], u[i], u[i], u[i]);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void foo() {\n" + " long * l;\n" + " printf(\"%d %x %u %f\", l[i], l[i], l[i], l[i]);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'long'.\n" + "[test.cpp:3]: (warning) %x in format string (no. 2) requires 'unsigned int' but the argument type is 'long'.\n" + "[test.cpp:3]: (warning) %u in format string (no. 3) requires 'unsigned int' but the argument type is 'long'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'long'.\n", errout.str()); + } void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings