CheckIO: Changed severity for '.. aka' warnings to portability. If type is compatible then it's just a possible portability issue.

This commit is contained in:
Daniel Marjamäki 2016-09-11 17:05:01 +02:00
parent f0797c3924
commit 6b55acd7af
3 changed files with 174 additions and 158 deletions

View File

@ -1797,7 +1797,8 @@ void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, cons
void CheckIO::invalidScanfArgTypeError_s(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidScanfArgTypeError_s(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a \'";
@ -1808,11 +1809,12 @@ void CheckIO::invalidScanfArgTypeError_s(const Token* tok, unsigned int numForma
errmsg << " *\' but the argument type is "; errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidScanfArgType_s", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidScanfArgType_s", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidScanfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned) void CheckIO::invalidScanfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'";
@ -1852,11 +1854,12 @@ void CheckIO::invalidScanfArgTypeError_int(const Token* tok, unsigned int numFor
errmsg << " *\' but the argument type is "; errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidScanfArgType_int", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidScanfArgType_int", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidScanfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidScanfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'";
@ -1869,38 +1872,41 @@ void CheckIO::invalidScanfArgTypeError_float(const Token* tok, unsigned int numF
errmsg << " *\' but the argument type is "; errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidScanfArgType_float", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidScanfArgType_float", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%s in format string (no. " << numFormat << ") requires \'char *\' but the argument type is "; errmsg << "%s in format string (no. " << numFormat << ") requires \'char *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_s", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_s", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%n in format string (no. " << numFormat << ") requires \'int *\' but the argument type is "; errmsg << "%n in format string (no. " << numFormat << ") requires \'int *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_n", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_n", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is "; errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_p", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_p", errmsg.str(), CWE686, false);
} }
static void printfFormatType(std::ostream& os, const std::string& specifier, bool isUnsigned) static void printfFormatType(std::ostream& os, const std::string& specifier, bool isUnsigned)
{ {
@ -1942,7 +1948,8 @@ static void printfFormatType(std::ostream& os, const std::string& specifier, boo
} }
void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires "; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires ";
@ -1950,11 +1957,12 @@ void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFo
errmsg << " but the argument type is "; errmsg << " but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_int", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_int", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires "; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires ";
@ -1962,12 +1970,13 @@ void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numF
errmsg << " but the argument type is "; errmsg << " but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_uint", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_uint", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires "; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires ";
@ -1975,11 +1984,12 @@ void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numF
errmsg << " but the argument type is "; errmsg << " but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_sint", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_sint", errmsg.str(), CWE686, false);
} }
void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
if (!_settings->isEnabled("warning")) const Severity::SeverityType severity = getSeverity(argInfo);
if (!_settings->isEnabled(Severity::toString(severity)))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'";
@ -1988,7 +1998,12 @@ void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, unsigned int num
errmsg << "double\' but the argument type is "; errmsg << "double\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_float", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_float", errmsg.str(), CWE686, false);
}
Severity::SeverityType CheckIO::getSeverity(const CheckIO::ArgumentInfo *argInfo) const
{
return (argInfo && argInfo->typeToken && !argInfo->typeToken->originalName().empty()) ? Severity::portability : Severity::warning;
} }
void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo) void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)

View File

@ -128,6 +128,7 @@ private:
void invalidLengthModifierError(const Token* tok, unsigned int numFormat, const std::string& modifier); void invalidLengthModifierError(const Token* tok, unsigned int numFormat, const std::string& modifier);
void invalidScanfFormatWidthError(const Token* tok, unsigned int numFormat, int width, const Variable *var, char c); void invalidScanfFormatWidthError(const Token* tok, unsigned int numFormat, int width, const Variable *var, char c);
static void argumentType(std::ostream & s, const ArgumentInfo * argInfo); static void argumentType(std::ostream & s, const ArgumentInfo * argInfo);
Severity::SeverityType getSeverity(const ArgumentInfo *argInfo) const;
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
CheckIO c(nullptr, settings, errorLogger); CheckIO c(nullptr, settings, errorLogger);

View File

@ -755,7 +755,7 @@ private:
"[test.cpp:1]: (warning) " FORMAT " in format string (no. 1) requires '" FORMATSTR " *' but the argument type is '" TYPE " *'.\n" "[test.cpp:1]: (warning) " FORMAT " in format string (no. 1) requires '" FORMATSTR " *' but the argument type is '" TYPE " *'.\n"
#define TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE) \ #define TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE) \
"[test.cpp:1]: (warning) " FORMAT " in format string (no. 1) requires '" FORMATSTR " *' but the argument type is '" TYPE " * {aka " AKATYPE " *}'.\n" "[test.cpp:1]: (portability) " FORMAT " in format string (no. 1) requires '" FORMATSTR " *' but the argument type is '" TYPE " * {aka " AKATYPE " *}'.\n"
#define TEST_SCANF_NOWARN(FORMAT, FORMATSTR, TYPE) \ #define TEST_SCANF_NOWARN(FORMAT, FORMATSTR, TYPE) \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix32); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix32); \
@ -778,33 +778,33 @@ private:
ASSERT_EQUALS(TEST_SCANF_ERR(FORMAT,FORMATSTR,TYPE), errout.str()); ASSERT_EQUALS(TEST_SCANF_ERR(FORMAT,FORMATSTR,TYPE), errout.str());
#define TEST_SCANF_WARN_AKA(FORMAT, FORMATSTR, TYPE, AKATYPE, AKATYPE_WIN64) \ #define TEST_SCANF_WARN_AKA(FORMAT, FORMATSTR, TYPE, AKATYPE, AKATYPE_WIN64) \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix32); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Unix32); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \ ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix64); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Unix64); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \ ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Win32A); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Win32A); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \ ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Win64); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Win64); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE_WIN64), errout.str()); ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE_WIN64), errout.str());
#define TEST_SCANF_WARN_AKA_WIN64(FORMAT, FORMATSTR, TYPE, AKATYPE_WIN64) \ #define TEST_SCANF_WARN_AKA_WIN64(FORMAT, FORMATSTR, TYPE, AKATYPE_WIN64) \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix32); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Unix32); \
ASSERT_EQUALS("", errout.str()); \ ASSERT_EQUALS("", errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix64); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Unix64); \
ASSERT_EQUALS("", errout.str()); \ ASSERT_EQUALS("", errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Win32A); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Win32A); \
ASSERT_EQUALS("", errout.str()); \ ASSERT_EQUALS("", errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Win64); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Win64); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE_WIN64), errout.str()); ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE_WIN64), errout.str());
#define TEST_SCANF_WARN_AKA_WIN32(FORMAT, FORMATSTR, TYPE, AKATYPE) \ #define TEST_SCANF_WARN_AKA_WIN32(FORMAT, FORMATSTR, TYPE, AKATYPE) \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix32); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Unix32); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \ ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Unix64); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Unix64); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \ ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Win32A); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Win32A); \
ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \ ASSERT_EQUALS(TEST_SCANF_ERR_AKA(FORMAT,FORMATSTR,TYPE,AKATYPE), errout.str()); \
check(TEST_SCANF_CODE(FORMAT,TYPE), true, false, Settings::Win64); \ check(TEST_SCANF_CODE(FORMAT,TYPE), true, true, Settings::Win64); \
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
void testScanfArgument() { void testScanfArgument() {
@ -1325,16 +1325,16 @@ private:
" scanf(\"%zd\", &s2);\n" " scanf(\"%zd\", &s2);\n"
" scanf(\"%zd\", &s3);\n" " scanf(\"%zd\", &s3);\n"
"}\n"; "}\n";
std::string result("[test.cpp:5]: (warning) %zd in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long *}'.\n"); std::string result("[test.cpp:5]: (portability) %zd in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long *}'.\n");
std::string result_win64("[test.cpp:5]: (warning) %zd in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long long *}'.\n"); std::string result_win64("[test.cpp:5]: (portability) %zd in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long long *}'.\n");
check(code, false, false, Settings::Unix32); check(code, false, true, Settings::Unix32);
ASSERT_EQUALS(result, errout.str()); ASSERT_EQUALS(result, errout.str());
check(code, false, false, Settings::Unix64); check(code, false, true, Settings::Unix64);
ASSERT_EQUALS(result, errout.str()); ASSERT_EQUALS(result, errout.str());
check(code, false, false, Settings::Win32A); check(code, false, true, Settings::Win32A);
ASSERT_EQUALS(result, errout.str()); ASSERT_EQUALS(result, errout.str());
check(code, false, false, Settings::Win64); check(code, false, true, Settings::Win64);
ASSERT_EQUALS(result_win64, errout.str()); ASSERT_EQUALS(result_win64, errout.str());
} }
{ {
@ -1578,58 +1578,58 @@ private:
check("void foo(size_t s, ptrdiff_t p) {\n" check("void foo(size_t s, ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Unix32); "}", false, true, Settings::Unix32);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str());
check("void foo(std::size_t s, std::ptrdiff_t p) {\n" check("void foo(std::size_t s, std::ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Unix32); "}", false, true, Settings::Unix32);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long}'.\n", errout.str());
check("void foo(size_t s, ptrdiff_t p) {\n" check("void foo(size_t s, ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Unix64); "}", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str());
check("void foo(std::size_t s, std::ptrdiff_t p) {\n" check("void foo(std::size_t s, std::ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Unix64); "}", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long}'.\n", errout.str());
check("void foo(size_t s, ptrdiff_t p) {\n" check("void foo(size_t s, ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Win32A); "}", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str());
check("void foo(std::size_t s, std::ptrdiff_t p) {\n" check("void foo(std::size_t s, std::ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Win32A); "}", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long}'.\n", errout.str());
check("void foo(size_t s, ptrdiff_t p) {\n" check("void foo(size_t s, ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Win64); "}", false, true, Settings::Win64);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'size_t {aka unsigned long long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'ptrdiff_t {aka long long}'.\n", errout.str());
check("void foo(std::size_t s, std::ptrdiff_t p) {\n" check("void foo(std::size_t s, std::ptrdiff_t p) {\n"
" printf(\"%zd\", s);\n" " printf(\"%zd\", s);\n"
" printf(\"%tu\", p);\n" " printf(\"%tu\", p);\n"
"}", false, false, Settings::Win64); "}", false, true, Settings::Win64);
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long long}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %zd in format string (no. 1) requires 'ssize_t' but the argument type is 'std::size_t {aka unsigned long long}'.\n"
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long long}'.\n", errout.str()); "[test.cpp:3]: (portability) %tu in format string (no. 1) requires 'unsigned ptrdiff_t' but the argument type is 'std::ptrdiff_t {aka long long}'.\n", errout.str());
check("void foo(unsigned int i) {\n" check("void foo(unsigned int i) {\n"
" printf(\"%ld\", i);\n" " printf(\"%ld\", i);\n"
@ -1921,67 +1921,67 @@ private:
"void foo() {\n" "void foo() {\n"
" printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n" " printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n"
" printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n" " printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n"
"}\n", false, false, Settings::Win32A); "}\n", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:4]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:4]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:4]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:4]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:5]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str()); "[test.cpp:5]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str());
check("std::vector<int> v;\n" check("std::vector<int> v;\n"
"std::string s;\n" "std::string s;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n" " printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n"
" printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n" " printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n"
"}\n", false, false, Settings::Win64); "}\n", false, true, Settings::Win64);
ASSERT_EQUALS("[test.cpp:4]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long long}'.\n" ASSERT_EQUALS("[test.cpp:4]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long long}'.\n"
"[test.cpp:4]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long long}'.\n" "[test.cpp:4]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long long}'.\n"
"[test.cpp:5]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long long}'.\n" "[test.cpp:5]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long long}'.\n"
"[test.cpp:5]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long long}'.\n", errout.str()); "[test.cpp:5]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long long}'.\n", errout.str());
check("std::vector<int> v;\n" check("std::vector<int> v;\n"
"std::string s;\n" "std::string s;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n" " printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n"
" printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n" " printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n"
"}\n", false, false, Settings::Unix32); "}\n", false, true, Settings::Unix32);
ASSERT_EQUALS("[test.cpp:4]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:4]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:4]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:4]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:5]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str()); "[test.cpp:5]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str());
check("std::vector<int> v;\n" check("std::vector<int> v;\n"
"std::string s;\n" "std::string s;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n" " printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n"
" printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n" " printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:4]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:4]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:4]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:4]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:5]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str()); "[test.cpp:5]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str());
check("class Fred : public std::vector<int> {} v;\n" check("class Fred : public std::vector<int> {} v;\n"
"std::string s;\n" "std::string s;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n" " printf(\"%zu %Iu %d %f\", v.size(), v.size(), v.size(), v.size());\n"
" printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n" " printf(\"%zu %Iu %d %f\", s.size(), s.size(), s.size(), s.size());\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:4]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:4]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:4]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:4]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:5]: (portability) %d in format string (no. 3) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:5]: (warning) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str()); "[test.cpp:5]: (portability) %f in format string (no. 4) requires 'double' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str());
check("class Fred : public std::vector<int> {} v;\n" check("class Fred : public std::vector<int> {} v;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%d %u %f\", v[0], v[0], v[0]);\n" " printf(\"%d %u %f\", v[0], v[0], v[0]);\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'int'.\n" ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'int'.\n"
"[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'int'.\n", errout.str()); "[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'int'.\n", errout.str());
check("std::string s;\n" check("std::string s;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%s %p %u %d %f\", s.c_str(), s.c_str(), s.c_str(), s.c_str(), s.c_str());\n" " printf(\"%s %p %u %d %f\", s.c_str(), s.c_str(), s.c_str(), s.c_str(), s.c_str());\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 3) requires 'unsigned int' but the argument type is 'const char *'.\n" ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 3) requires 'unsigned int' but the argument type is 'const char *'.\n"
"[test.cpp:3]: (warning) %d in format string (no. 4) requires 'int' but the argument type is 'const char *'.\n" "[test.cpp:3]: (warning) %d in format string (no. 4) requires 'int' but the argument type is 'const char *'.\n"
"[test.cpp:3]: (warning) %f in format string (no. 5) requires 'double' but the argument type is 'const char *'.\n", errout.str()); "[test.cpp:3]: (warning) %f in format string (no. 5) requires 'double' but the argument type is 'const char *'.\n", errout.str());
@ -1997,16 +1997,16 @@ private:
" printf(\"%u %u\", array.size(), s);\n" " printf(\"%u %u\", array.size(), s);\n"
" printf(\"%lu %lu\", array.size(), s);\n" " printf(\"%lu %lu\", array.size(), s);\n"
" printf(\"%llu %llu\", array.size(), s);\n" " printf(\"%llu %llu\", array.size(), s);\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:8]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'char *'.\n" ASSERT_EQUALS("[test.cpp:8]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'char *'.\n"
"[test.cpp:8]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'char *'.\n" "[test.cpp:8]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'char *'.\n"
"[test.cpp:8]: (warning) %u in format string (no. 3) requires 'unsigned int' but the argument type is 'char *'.\n" "[test.cpp:8]: (warning) %u in format string (no. 3) requires 'unsigned int' but the argument type is 'char *'.\n"
"[test.cpp:9]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:9]: (portability) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:9]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:9]: (portability) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:10]: (warning) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:10]: (portability) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:10]: (warning) %lu in format string (no. 2) requires 'unsigned long' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:10]: (portability) %lu in format string (no. 2) requires 'unsigned long' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:11]: (warning) %llu in format string (no. 1) requires 'unsigned long long' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:11]: (portability) %llu in format string (no. 1) requires 'unsigned long long' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:11]: (warning) %llu in format string (no. 2) requires 'unsigned long long' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str()); "[test.cpp:11]: (portability) %llu in format string (no. 2) requires 'unsigned long long' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str());
check("bool b; bool bf();\n" check("bool b; bool bf();\n"
"char c; char cf();\n" "char c; char cf();\n"
@ -2021,10 +2021,10 @@ private:
"char ca[3];\n" "char ca[3];\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%td %zd %d %d %d %d %d %d %d %d %d %d %d\", pt, pt, b, c, sc, uc, s, us, st, pt, pc, cl, ca);\n" " printf(\"%td %zd %d %d %d %d %d %d %d %d %d %d %d\", pt, pt, b, c, sc, uc, s, us, st, pt, pc, cl, ca);\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:13]: (warning) %zd in format string (no. 2) requires 'ssize_t' but the argument type is 'ptrdiff_t {aka long}'.\n" ASSERT_EQUALS("[test.cpp:13]: (portability) %zd in format string (no. 2) requires 'ssize_t' but the argument type is 'ptrdiff_t {aka long}'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 9) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:13]: (portability) %d in format string (no. 9) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 10) requires 'int' but the argument type is 'ptrdiff_t {aka long}'.\n" "[test.cpp:13]: (portability) %d in format string (no. 10) requires 'int' but the argument type is 'ptrdiff_t {aka long}'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 11) requires 'int' but the argument type is 'char *'.\n" "[test.cpp:13]: (warning) %d in format string (no. 11) requires 'int' but the argument type is 'char *'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 12) requires 'int' but the argument type is 'char *'.\n" "[test.cpp:13]: (warning) %d in format string (no. 12) requires 'int' but the argument type is 'char *'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 13) requires 'int' but the argument type is 'char *'.\n", errout.str()); "[test.cpp:13]: (warning) %d in format string (no. 13) requires 'int' but the argument type is 'char *'.\n", errout.str());
@ -2042,15 +2042,15 @@ private:
"char ca[3];\n" "char ca[3];\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\", b, c, sc, uc, s, us, st, pt, pc, cl, ca);\n" " printf(\"%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\", b, c, sc, uc, s, us, st, pt, pc, cl, ca);\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:13]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'bool'.\n" ASSERT_EQUALS("[test.cpp:13]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'bool'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 2) requires 'long' but the argument type is 'char'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 2) requires 'long' but the argument type is 'char'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'signed char'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'signed char'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 4) requires 'long' but the argument type is 'unsigned char'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 4) requires 'long' but the argument type is 'unsigned char'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 5) requires 'long' but the argument type is 'short'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 5) requires 'long' but the argument type is 'short'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 6) requires 'long' but the argument type is 'unsigned short'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 6) requires 'long' but the argument type is 'unsigned short'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 7) requires 'long' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:13]: (portability) %ld in format string (no. 7) requires 'long' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 8) requires 'long' but the argument type is 'ptrdiff_t {aka long}'.\n" "[test.cpp:13]: (portability) %ld in format string (no. 8) requires 'long' but the argument type is 'ptrdiff_t {aka long}'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 9) requires 'long' but the argument type is 'char *'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 9) requires 'long' but the argument type is 'char *'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 10) requires 'long' but the argument type is 'char *'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 10) requires 'long' but the argument type is 'char *'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 11) requires 'long' but the argument type is 'char *'.\n", errout.str()); "[test.cpp:13]: (warning) %ld in format string (no. 11) requires 'long' but the argument type is 'char *'.\n", errout.str());
@ -2069,10 +2069,10 @@ private:
"char ca[3];\n" "char ca[3];\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%td %zd %d %d %d %d %d %d %d %d %d\", ptf(), ptf(), bf(), cf(), scf(), ucf(), sf(), usf(), stf(), ptf(), pcf());\n" " printf(\"%td %zd %d %d %d %d %d %d %d %d %d\", ptf(), ptf(), bf(), cf(), scf(), ucf(), sf(), usf(), stf(), ptf(), pcf());\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:13]: (warning) %zd in format string (no. 2) requires 'ssize_t' but the argument type is 'ptrdiff_t {aka signed long}'.\n" ASSERT_EQUALS("[test.cpp:13]: (portability) %zd in format string (no. 2) requires 'ssize_t' but the argument type is 'ptrdiff_t {aka signed long}'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 9) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:13]: (portability) %d in format string (no. 9) requires 'int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 10) requires 'int' but the argument type is 'ptrdiff_t {aka signed long}'.\n" "[test.cpp:13]: (portability) %d in format string (no. 10) requires 'int' but the argument type is 'ptrdiff_t {aka signed long}'.\n"
"[test.cpp:13]: (warning) %d in format string (no. 11) requires 'int' but the argument type is 'char *'.\n", errout.str()); "[test.cpp:13]: (warning) %d in format string (no. 11) requires 'int' but the argument type is 'char *'.\n", errout.str());
check("bool b; bool bf();\n" check("bool b; bool bf();\n"
@ -2088,15 +2088,15 @@ private:
"char ca[3];\n" "char ca[3];\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%ld %ld %ld %ld %ld %ld %ld %ld %ld\", bf(), cf(), scf(), ucf(), sf(), usf(), stf(), ptf(), pcf());\n" " printf(\"%ld %ld %ld %ld %ld %ld %ld %ld %ld\", bf(), cf(), scf(), ucf(), sf(), usf(), stf(), ptf(), pcf());\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:13]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'bool'.\n" ASSERT_EQUALS("[test.cpp:13]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'bool'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 2) requires 'long' but the argument type is 'char'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 2) requires 'long' but the argument type is 'char'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'signed char'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 3) requires 'long' but the argument type is 'signed char'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 4) requires 'long' but the argument type is 'unsigned char'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 4) requires 'long' but the argument type is 'unsigned char'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 5) requires 'long' but the argument type is 'signed short'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 5) requires 'long' but the argument type is 'signed short'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 6) requires 'long' but the argument type is 'unsigned short'.\n" "[test.cpp:13]: (warning) %ld in format string (no. 6) requires 'long' but the argument type is 'unsigned short'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 7) requires 'long' but the argument type is 'size_t {aka unsigned long}'.\n" "[test.cpp:13]: (portability) %ld in format string (no. 7) requires 'long' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 8) requires 'long' but the argument type is 'ptrdiff_t {aka signed long}'.\n" "[test.cpp:13]: (portability) %ld in format string (no. 8) requires 'long' but the argument type is 'ptrdiff_t {aka signed long}'.\n"
"[test.cpp:13]: (warning) %ld in format string (no. 9) requires 'long' but the argument type is 'char *'.\n", errout.str()); "[test.cpp:13]: (warning) %ld in format string (no. 9) requires 'long' but the argument type is 'char *'.\n", errout.str());
check("struct A {};\n" check("struct A {};\n"
@ -2108,8 +2108,8 @@ private:
" printf(\"%p %d\", b[0], b[0]);\n" " printf(\"%p %d\", b[0], b[0]);\n"
" printf(\"%p %d\", c[0], c[0]);\n" " printf(\"%p %d\", c[0], c[0]);\n"
" printf(\"%p %d\", s.c_str(), s.c_str());\n" " printf(\"%p %d\", s.c_str(), s.c_str());\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:6]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:6]: (portability) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:7]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const int *'.\n" "[test.cpp:7]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const int *'.\n"
"[test.cpp:8]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const struct A *'.\n" "[test.cpp:8]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const struct A *'.\n"
"[test.cpp:9]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const char *'.\n", errout.str()); "[test.cpp:9]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const char *'.\n", errout.str());
@ -2133,16 +2133,16 @@ private:
"buffer<int> b;\n" "buffer<int> b;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%u\", b.size());\n" " printf(\"%u\", b.size());\n"
"}\n", false, false, Settings::Unix64); "}\n", false, true, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:7]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (portability) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'size_t {aka unsigned long}'.\n", errout.str());
check("DWORD a;\n" check("DWORD a;\n"
"DWORD_PTR b;\n" "DWORD_PTR b;\n"
"void foo() {\n" "void foo() {\n"
" printf(\"%u %u\", a, b);\n" " printf(\"%u %u\", a, b);\n"
"}\n", false, false, Settings::Win32A); "}\n", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:4]: (warning) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'DWORD {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:4]: (portability) %u in format string (no. 1) requires 'unsigned int' but the argument type is 'DWORD {aka unsigned long}'.\n"
"[test.cpp:4]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'DWORD_PTR {aka unsigned long}'.\n", errout.str()); "[test.cpp:4]: (portability) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'DWORD_PTR {aka unsigned long}'.\n", errout.str());
check("unsigned long a[] = { 1, 2 };\n" check("unsigned long a[] = { 1, 2 };\n"
"void foo() {\n" "void foo() {\n"
@ -2355,13 +2355,13 @@ private:
" printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n" " printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n"
" printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n" " printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n"
" printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n" " printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n"
"}", false, false, Settings::Win32A); "}", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:8]: (warning) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'size_t {aka unsigned long}'.\n" ASSERT_EQUALS("[test.cpp:8]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'size_t {aka unsigned long}'.\n"
"[test.cpp:9]: (warning) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'ptrdiff_t {aka long}'.\n" "[test.cpp:9]: (portability) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'ptrdiff_t {aka long}'.\n"
"[test.cpp:10]: (warning) %I32u in format string (no. 2) requires 'unsigned __int32' but the argument type is '__int32 {aka int}'.\n" "[test.cpp:10]: (portability) %I32u in format string (no. 2) requires 'unsigned __int32' but the argument type is '__int32 {aka int}'.\n"
"[test.cpp:11]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" "[test.cpp:11]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n"
"[test.cpp:12]: (warning) %I64u in format string (no. 2) requires 'unsigned __int64' but the argument type is '__int64 {aka long long}'.\n" "[test.cpp:12]: (portability) %I64u in format string (no. 2) requires 'unsigned __int64' but the argument type is '__int64 {aka long long}'.\n"
"[test.cpp:13]: (warning) %I64d in format string (no. 1) requires '__int64' but the argument type is 'unsigned __int64 {aka unsigned long long}'.\n", errout.str()); "[test.cpp:13]: (portability) %I64d in format string (no. 1) requires '__int64' but the argument type is 'unsigned __int64 {aka unsigned long long}'.\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" size_t s;\n" " size_t s;\n"
@ -2376,13 +2376,13 @@ private:
" printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n" " printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n"
" printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n" " printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n"
" printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n" " printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n"
"}", false, false, Settings::Win64); "}", false, true, Settings::Win64);
ASSERT_EQUALS("[test.cpp:8]: (warning) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'size_t {aka unsigned long long}'.\n" ASSERT_EQUALS("[test.cpp:8]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t' but the argument type is 'size_t {aka unsigned long long}'.\n"
"[test.cpp:9]: (warning) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'ptrdiff_t {aka long long}'.\n" "[test.cpp:9]: (portability) %Iu in format string (no. 2) requires 'size_t' but the argument type is 'ptrdiff_t {aka long long}'.\n"
"[test.cpp:10]: (warning) %I32u in format string (no. 2) requires 'unsigned __int32' but the argument type is '__int32 {aka int}'.\n" "[test.cpp:10]: (portability) %I32u in format string (no. 2) requires 'unsigned __int32' but the argument type is '__int32 {aka int}'.\n"
"[test.cpp:11]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" "[test.cpp:11]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n"
"[test.cpp:12]: (warning) %I64u in format string (no. 2) requires 'unsigned __int64' but the argument type is '__int64 {aka long long}'.\n" "[test.cpp:12]: (portability) %I64u in format string (no. 2) requires 'unsigned __int64' but the argument type is '__int64 {aka long long}'.\n"
"[test.cpp:13]: (warning) %I64d in format string (no. 1) requires '__int64' but the argument type is 'unsigned __int64 {aka unsigned long long}'.\n", errout.str()); "[test.cpp:13]: (portability) %I64d in format string (no. 1) requires '__int64' but the argument type is 'unsigned __int64 {aka unsigned long long}'.\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" size_t s;\n" " size_t s;\n"
@ -2420,23 +2420,23 @@ private:
// ticket #5264 // ticket #5264
check("void foo(LPARAM lp, WPARAM wp, LRESULT lr) {\n" check("void foo(LPARAM lp, WPARAM wp, LRESULT lr) {\n"
" printf(\"%Ix %Ix %Ix\", lp, wp, lr);\n" " printf(\"%Ix %Ix %Ix\", lp, wp, lr);\n"
"}\n", false, false, Settings::Win64); "}\n", false, true, Settings::Win64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(LPARAM lp, WPARAM wp, LRESULT lr) {\n" check("void foo(LPARAM lp, WPARAM wp, LRESULT lr) {\n"
" printf(\"%Ix %Ix %Ix\", lp, wp, lr);\n" " printf(\"%Ix %Ix %Ix\", lp, wp, lr);\n"
"}\n", false, false, Settings::Win32A); "}\n", false, true, Settings::Win32A);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(UINT32 a, ::UINT32 b, Fred::UINT32 c) {\n" check("void foo(UINT32 a, ::UINT32 b, Fred::UINT32 c) {\n"
" printf(\"%d %d %d\n\", a, b, c);\n" " printf(\"%d %d %d\n\", a, b, c);\n"
"};\n", false, false, Settings::Win32A); "};\n", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'UINT32 {aka unsigned int}'.\n" ASSERT_EQUALS("[test.cpp:2]: (portability) %d in format string (no. 1) requires 'int' but the argument type is 'UINT32 {aka unsigned int}'.\n"
"[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'UINT32 {aka unsigned int}'.\n", errout.str()); "[test.cpp:2]: (portability) %d in format string (no. 2) requires 'int' but the argument type is 'UINT32 {aka unsigned int}'.\n", errout.str());
check("void foo(LPCVOID a, ::LPCVOID b, Fred::LPCVOID c) {\n" check("void foo(LPCVOID a, ::LPCVOID b, Fred::LPCVOID c) {\n"
" printf(\"%d %d %d\n\", a, b, c);\n" " printf(\"%d %d %d\n\", a, b, c);\n"
"};\n", false, false, Settings::Win32A); "};\n", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'const void *'.\n" ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'const void *'.\n"
"[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const void *'.\n", errout.str()); "[test.cpp:2]: (warning) %d in format string (no. 2) requires 'int' but the argument type is 'const void *'.\n", errout.str());
@ -2456,13 +2456,13 @@ private:
" scanf(\"%I32d %I32u %I32x\", &u32, &u32, &u32);\n" " scanf(\"%I32d %I32u %I32x\", &u32, &u32, &u32);\n"
" scanf(\"%I64d %I64u %I64x\", &i64, &i64, &i64);\n" " scanf(\"%I64d %I64u %I64x\", &i64, &i64, &i64);\n"
" scanf(\"%I64d %I64u %I64x\", &u64, &u64, &u64);\n" " scanf(\"%I64d %I64u %I64x\", &u64, &u64, &u64);\n"
"}", false, false, Settings::Win32A); "}", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:8]: (warning) %Id in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long *}'.\n" ASSERT_EQUALS("[test.cpp:8]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:9]: (warning) %Iu in format string (no. 2) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long *}'.\n" "[test.cpp:9]: (portability) %Iu in format string (no. 2) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long *}'.\n"
"[test.cpp:10]: (warning) %I32u in format string (no. 2) requires 'unsigned __int32 *' but the argument type is '__int32 * {aka signed int *}'.\n" "[test.cpp:10]: (portability) %I32u in format string (no. 2) requires 'unsigned __int32 *' but the argument type is '__int32 * {aka signed int *}'.\n"
"[test.cpp:11]: (warning) %I32d in format string (no. 1) requires '__int32 *' but the argument type is 'unsigned __int32 * {aka unsigned int *}'.\n" "[test.cpp:11]: (portability) %I32d in format string (no. 1) requires '__int32 *' but the argument type is 'unsigned __int32 * {aka unsigned int *}'.\n"
"[test.cpp:12]: (warning) %I64u in format string (no. 2) requires 'unsigned __int64 *' but the argument type is '__int64 * {aka signed long long *}'.\n" "[test.cpp:12]: (portability) %I64u in format string (no. 2) requires 'unsigned __int64 *' but the argument type is '__int64 * {aka signed long long *}'.\n"
"[test.cpp:13]: (warning) %I64d in format string (no. 1) requires '__int64 *' but the argument type is 'unsigned __int64 * {aka unsigned long long *}'.\n", errout.str()); "[test.cpp:13]: (portability) %I64d in format string (no. 1) requires '__int64 *' but the argument type is 'unsigned __int64 * {aka unsigned long long *}'.\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" size_t s;\n" " size_t s;\n"
@ -2477,13 +2477,13 @@ private:
" scanf(\"%I32d %I32u %I32x\", &u32, &u32, &u32);\n" " scanf(\"%I32d %I32u %I32x\", &u32, &u32, &u32);\n"
" scanf(\"%I64d %I64u %I64x\", &i64, &i64, &i64);\n" " scanf(\"%I64d %I64u %I64x\", &i64, &i64, &i64);\n"
" scanf(\"%I64d %I64u %I64x\", &u64, &u64, &u64);\n" " scanf(\"%I64d %I64u %I64x\", &u64, &u64, &u64);\n"
"}", false, false, Settings::Win64); "}", false, true, Settings::Win64);
ASSERT_EQUALS("[test.cpp:8]: (warning) %Id in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long long *}'.\n" ASSERT_EQUALS("[test.cpp:8]: (portability) %Id in format string (no. 1) requires 'ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long long *}'.\n"
"[test.cpp:9]: (warning) %Iu in format string (no. 2) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long long *}'.\n" "[test.cpp:9]: (portability) %Iu in format string (no. 2) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka signed long long *}'.\n"
"[test.cpp:10]: (warning) %I32u in format string (no. 2) requires 'unsigned __int32 *' but the argument type is '__int32 * {aka signed int *}'.\n" "[test.cpp:10]: (portability) %I32u in format string (no. 2) requires 'unsigned __int32 *' but the argument type is '__int32 * {aka signed int *}'.\n"
"[test.cpp:11]: (warning) %I32d in format string (no. 1) requires '__int32 *' but the argument type is 'unsigned __int32 * {aka unsigned int *}'.\n" "[test.cpp:11]: (portability) %I32d in format string (no. 1) requires '__int32 *' but the argument type is 'unsigned __int32 * {aka unsigned int *}'.\n"
"[test.cpp:12]: (warning) %I64u in format string (no. 2) requires 'unsigned __int64 *' but the argument type is '__int64 * {aka signed long long *}'.\n" "[test.cpp:12]: (portability) %I64u in format string (no. 2) requires 'unsigned __int64 *' but the argument type is '__int64 * {aka signed long long *}'.\n"
"[test.cpp:13]: (warning) %I64d in format string (no. 1) requires '__int64 *' but the argument type is 'unsigned __int64 * {aka unsigned long long *}'.\n", errout.str()); "[test.cpp:13]: (portability) %I64d in format string (no. 1) requires '__int64 *' but the argument type is 'unsigned __int64 * {aka unsigned long long *}'.\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" size_t s;\n" " size_t s;\n"
@ -2525,7 +2525,7 @@ private:
" String string;\n" " String string;\n"
" string.Format(\"%I32d\", u32);\n" " string.Format(\"%I32d\", u32);\n"
" string.AppendFormat(\"%I32d\", u32);\n" " string.AppendFormat(\"%I32d\", u32);\n"
"}", false, false, Settings::Win32A); "}", false, true, Settings::Win32A);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo() {\n" check("void foo() {\n"
@ -2533,7 +2533,7 @@ private:
" CString string;\n" " CString string;\n"
" string.Format(\"%I32d\", u32);\n" " string.Format(\"%I32d\", u32);\n"
" string.AppendFormat(\"%I32d\", u32);\n" " string.AppendFormat(\"%I32d\", u32);\n"
"}", false, false, Settings::Unix32); "}", false, true, Settings::Unix32);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo() {\n" check("void foo() {\n"
@ -2542,10 +2542,10 @@ private:
" string.Format(\"%I32d\", u32);\n" " string.Format(\"%I32d\", u32);\n"
" string.AppendFormat(\"%I32d\", u32);\n" " string.AppendFormat(\"%I32d\", u32);\n"
" CString::Format(\"%I32d\", u32);\n" " CString::Format(\"%I32d\", u32);\n"
"}", false, false, Settings::Win32A); "}", false, true, Settings::Win32A);
ASSERT_EQUALS("[test.cpp:4]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" ASSERT_EQUALS("[test.cpp:4]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n"
"[test.cpp:5]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" "[test.cpp:5]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n"
"[test.cpp:6]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n", errout.str()); "[test.cpp:6]: (portability) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n", errout.str());
} }
void testMicrosoftSecurePrintfArgument() { void testMicrosoftSecurePrintfArgument() {