Fixed #7710 (%h and %hh printf type size specifiers not supported)
This commit is contained in:
parent
28e14f0b94
commit
6043a27065
|
@ -1056,6 +1056,13 @@ void CheckIO::checkFormatString(const Token * const tok,
|
||||||
invalidPrintfArgTypeError_int(tok, numFormat, specifier, &argInfo);
|
invalidPrintfArgTypeError_int(tok, numFormat, specifier, &argInfo);
|
||||||
} else {
|
} else {
|
||||||
switch (specifier[0]) {
|
switch (specifier[0]) {
|
||||||
|
case 'h':
|
||||||
|
if (specifier[1] == 'h') {
|
||||||
|
if (argInfo.typeToken->str() != "char")
|
||||||
|
invalidPrintfArgTypeError_int(tok, numFormat, specifier, &argInfo);
|
||||||
|
} else if (argInfo.typeToken->str() != "short")
|
||||||
|
invalidPrintfArgTypeError_int(tok, numFormat, specifier, &argInfo);
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (specifier[1] == 'l') {
|
if (specifier[1] == 'l') {
|
||||||
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
|
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
|
||||||
|
@ -1121,6 +1128,13 @@ void CheckIO::checkFormatString(const Token * const tok,
|
||||||
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo);
|
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo);
|
||||||
} else {
|
} else {
|
||||||
switch (specifier[0]) {
|
switch (specifier[0]) {
|
||||||
|
case 'h':
|
||||||
|
if (specifier[1] == 'h') {
|
||||||
|
if (!(argInfo.typeToken->str() == "char" && !argInfo.typeToken->isUnsigned()))
|
||||||
|
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo);
|
||||||
|
} else if (!(argInfo.typeToken->str() == "short" && !argInfo.typeToken->isUnsigned()))
|
||||||
|
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo);
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (specifier[1] == 'l') {
|
if (specifier[1] == 'l') {
|
||||||
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
|
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
|
||||||
|
@ -1191,6 +1205,13 @@ void CheckIO::checkFormatString(const Token * const tok,
|
||||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||||
} else {
|
} else {
|
||||||
switch (specifier[0]) {
|
switch (specifier[0]) {
|
||||||
|
case 'h':
|
||||||
|
if (specifier[1] == 'h') {
|
||||||
|
if (!(argInfo.typeToken->str() == "char" && argInfo.typeToken->isUnsigned()))
|
||||||
|
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||||
|
} else if (!(argInfo.typeToken->str() == "short" && argInfo.typeToken->isUnsigned()))
|
||||||
|
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (specifier[1] == 'l') {
|
if (specifier[1] == 'l') {
|
||||||
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
|
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
|
||||||
|
@ -1888,6 +1909,11 @@ static void printfFormatType(std::ostream& os, const std::string& specifier, boo
|
||||||
os << (isUnsigned ? "unsigned " : "") << "long long";
|
os << (isUnsigned ? "unsigned " : "") << "long long";
|
||||||
else
|
else
|
||||||
os << (isUnsigned ? "unsigned " : "") << "long";
|
os << (isUnsigned ? "unsigned " : "") << "long";
|
||||||
|
} else if (specifier[0] == 'h') {
|
||||||
|
if (specifier[1] == 'h')
|
||||||
|
os << (isUnsigned ? "unsigned " : "") << "char";
|
||||||
|
else
|
||||||
|
os << (isUnsigned ? "unsigned " : "") << "short";
|
||||||
} else if (specifier.find("I32") != std::string::npos) {
|
} else if (specifier.find("I32") != std::string::npos) {
|
||||||
os << (isUnsigned ? "unsigned " : "") << "__int32";
|
os << (isUnsigned ? "unsigned " : "") << "__int32";
|
||||||
} else if (specifier.find("I64") != std::string::npos) {
|
} else if (specifier.find("I64") != std::string::npos) {
|
||||||
|
|
|
@ -1526,7 +1526,7 @@ private:
|
||||||
" printf(\"%hhx %hhd\", sc, uc);\n"
|
" printf(\"%hhx %hhd\", sc, uc);\n"
|
||||||
" printf(\"%hd %hu\", si, usi);\n"
|
" printf(\"%hd %hu\", si, usi);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hhd in format string (no. 2) requires 'char' but the argument type is 'unsigned char'.\n", errout.str());
|
||||||
|
|
||||||
check("void foo(long long int lli, unsigned long long int ulli, long int li, unsigned long int uli) {\n"
|
check("void foo(long long int lli, unsigned long long int ulli, long int li, unsigned long int uli) {\n"
|
||||||
" printf(\"%llo %llx\", lli, ulli);\n"
|
" printf(\"%llo %llx\", lli, ulli);\n"
|
||||||
|
@ -1570,8 +1570,8 @@ private:
|
||||||
" printf(\"%ld\", i);\n"
|
" printf(\"%ld\", i);\n"
|
||||||
" printf(\"%lld\", i);\n"
|
" printf(\"%lld\", i);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires 'int' but the argument type is 'unsigned int'.\n"
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires 'short' but the argument type is 'unsigned int'.\n"
|
||||||
"[test.cpp:3]: (warning) %hhd in format string (no. 1) requires 'int' but the argument type is 'unsigned int'.\n"
|
"[test.cpp:3]: (warning) %hhd in format string (no. 1) requires 'char' but the argument type is 'unsigned int'.\n"
|
||||||
"[test.cpp:4]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'unsigned int'.\n"
|
"[test.cpp:4]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'unsigned int'.\n"
|
||||||
"[test.cpp:5]: (warning) %lld in format string (no. 1) requires 'long long' but the argument type is 'unsigned int'.\n" , errout.str());
|
"[test.cpp:5]: (warning) %lld in format string (no. 1) requires 'long long' but the argument type is 'unsigned int'.\n" , errout.str());
|
||||||
|
|
||||||
|
@ -2251,6 +2251,70 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) %Ld in format string (no. 1) requires 'long long' but the argument type is 'int'.\n"
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %Ld in format string (no. 1) requires 'long long' but the argument type is 'int'.\n"
|
||||||
"[test.cpp:2]: (warning) %Lu in format string (no. 2) requires 'unsigned long long' but the argument type is 'unsigned int'.\n", errout.str());
|
"[test.cpp:2]: (warning) %Lu in format string (no. 2) requires 'unsigned long long' but the argument type is 'unsigned int'.\n", errout.str());
|
||||||
|
|
||||||
|
check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n"
|
||||||
|
" printf(\"%hhd %hhd %hhd %hhd %hhd %hhd %hhd %hhd\", c, uc, s, us, i, ui, l, ul);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hhd in format string (no. 2) requires 'char' but the argument type is 'unsigned char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhd in format string (no. 3) requires 'char' but the argument type is 'short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhd in format string (no. 4) requires 'char' but the argument type is 'unsigned short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhd in format string (no. 5) requires 'char' but the argument type is 'int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhd in format string (no. 6) requires 'char' but the argument type is 'unsigned int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhd in format string (no. 7) requires 'char' but the argument type is 'long'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhd in format string (no. 8) requires 'char' but the argument type is 'unsigned long'.\n", errout.str());
|
||||||
|
|
||||||
|
check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n"
|
||||||
|
" printf(\"%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu\", c, uc, s, us, i, ui, l, ul);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hhu in format string (no. 1) requires 'unsigned char' but the argument type is 'char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhu in format string (no. 3) requires 'unsigned char' but the argument type is 'short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhu in format string (no. 4) requires 'unsigned char' but the argument type is 'unsigned short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhu in format string (no. 5) requires 'unsigned char' but the argument type is 'int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhu in format string (no. 6) requires 'unsigned char' but the argument type is 'unsigned int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhu in format string (no. 7) requires 'unsigned char' but the argument type is 'long'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhu in format string (no. 8) requires 'unsigned char' but the argument type is 'unsigned long'.\n", errout.str());
|
||||||
|
|
||||||
|
check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n"
|
||||||
|
" printf(\"%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\", c, uc, s, us, i, ui, l, ul);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hhx in format string (no. 3) requires 'unsigned char' but the argument type is 'short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhx in format string (no. 4) requires 'unsigned char' but the argument type is 'unsigned short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhx in format string (no. 5) requires 'unsigned char' but the argument type is 'int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhx in format string (no. 6) requires 'unsigned char' but the argument type is 'unsigned int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhx in format string (no. 7) requires 'unsigned char' but the argument type is 'long'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hhx in format string (no. 8) requires 'unsigned char' but the argument type is 'unsigned long'.\n", errout.str());
|
||||||
|
|
||||||
|
check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n"
|
||||||
|
" printf(\"%hd %hd %hd %hd %hd %hd %hd %hd\", c, uc, s, us, i, ui, l, ul);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires 'short' but the argument type is 'char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hd in format string (no. 2) requires 'short' but the argument type is 'unsigned char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hd in format string (no. 4) requires 'short' but the argument type is 'unsigned short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hd in format string (no. 5) requires 'short' but the argument type is 'int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hd in format string (no. 6) requires 'short' but the argument type is 'unsigned int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hd in format string (no. 7) requires 'short' but the argument type is 'long'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hd in format string (no. 8) requires 'short' but the argument type is 'unsigned long'.\n", errout.str());
|
||||||
|
|
||||||
|
check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n"
|
||||||
|
" printf(\"%hu %hu %hu %hu %hu %hu %hu %hu\", c, uc, s, us, i, ui, l, ul);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hu in format string (no. 1) requires 'unsigned short' but the argument type is 'char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hu in format string (no. 2) requires 'unsigned short' but the argument type is 'unsigned char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hu in format string (no. 3) requires 'unsigned short' but the argument type is 'short'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hu in format string (no. 5) requires 'unsigned short' but the argument type is 'int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hu in format string (no. 6) requires 'unsigned short' but the argument type is 'unsigned int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hu in format string (no. 7) requires 'unsigned short' but the argument type is 'long'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hu in format string (no. 8) requires 'unsigned short' but the argument type is 'unsigned long'.\n", errout.str());
|
||||||
|
|
||||||
|
check("void foo(char c, unsigned char uc, short s, unsigned short us, int i, unsigned int ui, long l, unsigned long ul) {\n"
|
||||||
|
" printf(\"%hx %hx %hx %hx %hx %hx %hx %hx\", c, uc, s, us, i, ui, l, ul);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (warning) %hx in format string (no. 1) requires 'unsigned short' but the argument type is 'char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hx in format string (no. 2) requires 'unsigned short' but the argument type is 'unsigned char'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hx in format string (no. 5) requires 'unsigned short' but the argument type is 'int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hx in format string (no. 6) requires 'unsigned short' but the argument type is 'unsigned int'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hx in format string (no. 7) requires 'unsigned short' but the argument type is 'long'.\n"
|
||||||
|
"[test.cpp:2]: (warning) %hx in format string (no. 8) requires 'unsigned short' but the argument type is 'unsigned long'.\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