CheckIO: Improved handling of h, hh, l, and ll.
This commit is contained in:
parent
464dccc188
commit
20f81f92d9
|
@ -620,20 +620,34 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
case 'l': // Can be 'll' (long long int or unsigned long long int) or 'l' (long int or unsigned long int)
|
||||
// If the next character is the same (which makes 'hh' or 'll') then expect another alphabetical character
|
||||
if (i != formatString.end() && *(i+1) == *i) {
|
||||
if (i+1 != formatString.end() && !isalpha(*(i+2))) {
|
||||
if (i+1 != formatString.end()) {
|
||||
if (!isalpha(*(i+2))) {
|
||||
std::string modifier;
|
||||
modifier += *i;
|
||||
modifier += *(i+1);
|
||||
invalidLengthModifierError(tok, numFormat, modifier);
|
||||
done = true;
|
||||
} else {
|
||||
specifier = *i++;
|
||||
specifier += *i++;
|
||||
}
|
||||
} else {
|
||||
if (i != formatString.end() && !isalpha(*(i+1))) {
|
||||
done = true;
|
||||
}
|
||||
} else {
|
||||
if (i != formatString.end()) {
|
||||
if (!isalpha(*(i+1))) {
|
||||
std::string modifier;
|
||||
modifier += *i;
|
||||
invalidLengthModifierError(tok, numFormat, modifier);
|
||||
}
|
||||
}
|
||||
done = true;
|
||||
} else {
|
||||
specifier = *i++;
|
||||
}
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'I': // Microsoft extension: I for size_t and ptrdiff_t, I32 for __int32, and I64 for __int64
|
||||
if (i != formatString.end()) {
|
||||
|
@ -659,8 +673,10 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
std::string modifier;
|
||||
modifier += *i;
|
||||
invalidLengthModifierError(tok, numFormat, modifier);
|
||||
}
|
||||
done = true;
|
||||
} else {
|
||||
specifier = *i++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
done = true;
|
||||
|
|
|
@ -717,7 +717,7 @@ private:
|
|||
// False positive tests
|
||||
check("void foo(signed char sc, unsigned char uc, short int si, unsigned short int usi) {\n"
|
||||
" printf(\"%hhx %hhd\", sc, uc);\n"
|
||||
" printf(\"%hd %hi\", si, usi);\n"
|
||||
" printf(\"%hd %hu\", si, usi);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
|
@ -754,6 +754,25 @@ private:
|
|||
"[test.cpp:7]: (warning) 'z' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n"
|
||||
"[test.cpp:8]: (warning) 't' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n"
|
||||
"[test.cpp:9]: (warning) 'L' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n", errout.str());
|
||||
|
||||
check("void foo(unsigned int i) {\n"
|
||||
" printf(\"%hd\", i);\n"
|
||||
" printf(\"%hhd\", i);\n"
|
||||
" printf(\"%ld\", i);\n"
|
||||
" printf(\"%lld\", i);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires a signed integer given in the argument list.\n"
|
||||
"[test.cpp:3]: (warning) %hhd in format string (no. 1) requires a signed integer given in the argument list.\n"
|
||||
"[test.cpp:4]: (warning) %ld in format string (no. 1) requires a signed integer given in the argument list.\n"
|
||||
"[test.cpp:5]: (warning) %lld in format string (no. 1) requires a signed integer given in the argument list.\n" , errout.str());
|
||||
|
||||
check("void foo(size_t s, ptrdiff_t p) {\n"
|
||||
" printf(\"%zd\", s);\n"
|
||||
" printf(\"%tu\", p);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires a signed integer given in the argument list.\n"
|
||||
"[test.cpp:3]: (warning) %tu in format string (no. 1) requires an unsigned integer given in the argument list.\n", errout.str());
|
||||
|
||||
}
|
||||
|
||||
void testMicrosoftPrintfArgument() {
|
||||
|
|
Loading…
Reference in New Issue