CheckIO: Improved handling of %u
This commit is contained in:
parent
9ab6655d85
commit
921a1aaa4f
231
lib/checkio.cpp
231
lib/checkio.cpp
|
@ -574,10 +574,10 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
(!Token::Match(argInfo.typeToken, "bool|short|long|int|char|size_t") ||
|
||||
(specifier[0] == 'l' && (argInfo.typeToken->str() != "long" || (specifier[1] == 'l' && !argInfo.typeToken->isLong()))) ||
|
||||
(specifier.find("I64") != std::string::npos && (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())))) {
|
||||
invalidPrintfArgTypeError_int(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_int(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
} else if (argInfo.typeToken->type() == Token::eString) {
|
||||
invalidPrintfArgTypeError_int(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_int(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
done = true;
|
||||
break;
|
||||
|
@ -589,42 +589,62 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
(((argInfo.typeToken->isUnsigned() || !Token::Match(argInfo.typeToken, "bool|short|long|int")) && argInfo.typeToken->str() != "char") ||
|
||||
(specifier[0] == 'l' && (argInfo.typeToken->str() != "long" || (specifier[1] == 'l' && !argInfo.typeToken->isLong()))) ||
|
||||
(specifier.find("I64") != std::string::npos && (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())))) {
|
||||
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
} else if (argInfo.typeToken->type() == Token::eString) {
|
||||
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo);
|
||||
} else if (argInfo.typeToken->isUnsigned() || !Token::Match(argInfo.typeToken, "bool|short|int|long")) {
|
||||
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_sint(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
done = true;
|
||||
break;
|
||||
case 'u':
|
||||
specifier += *i;
|
||||
if (argInfo.functionInfo || argInfo.variableInfo) {
|
||||
if ((argInfo.isKnownType() && !argInfo.isArrayOrPointer()) &&
|
||||
(((!argInfo.typeToken->isUnsigned() || !Token::Match(argInfo.typeToken, "char|short|long|int")) && argInfo.typeToken->str() != "bool") ||
|
||||
(specifier[0] == 'l' && (argInfo.typeToken->str() != "long" || (specifier[1] == 'l' && !argInfo.typeToken->isLong()))) ||
|
||||
(specifier.find("I64") != std::string::npos && (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())))) {
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, argInfo.typeToken);
|
||||
if (argInfo.isKnownType() && !argInfo.isArrayOrPointer()) {
|
||||
if ((!argInfo.typeToken->isUnsigned() || !Token::Match(argInfo.typeToken, "char|short|long|int")) && argInfo.typeToken->str() != "bool") {
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
} else if ((specifier[0] == 'l' && (argInfo.typeToken->str() != "long" || (specifier[1] == 'l' && !argInfo.typeToken->isLong()))) ||
|
||||
(specifier.find("I64") != std::string::npos && (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong()))) {
|
||||
// %l requires long and %ll or %I64 requires long long
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
} else if ((specifier[0] == 'z' || (specifier[0] == 'I' && specifier[1] == 'u')) && argInfo.typeToken->originalName() != "size_t") {
|
||||
// use %z or %I on size_t
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
} else if (argInfo.typeToken->originalName() == "size_t" && (specifier[0] != 'z' && !(specifier[0] == 'I' && specifier[1] == 'u'))) {
|
||||
// size_t requires %z or %I
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
} else if ((!argInfo.element && argInfo.isArrayOrPointer()) ||
|
||||
(argInfo.element && !argInfo.isArrayOrPointer())) {
|
||||
// use %p on pointers and arrays
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
} else if (argInfo.typeToken->type() == Token::eString) {
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
} else {
|
||||
if (((!argInfo.typeToken->isUnsigned() || !Token::Match(argInfo.typeToken, "char|short|long|int")) && argInfo.typeToken->str() != "bool") ||
|
||||
(specifier[0] == 'l' && (argInfo.typeToken->str() != "long" || (specifier[1] == 'l' && !argInfo.typeToken->isLong()))) ||
|
||||
(specifier.find("I64") != std::string::npos && (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong()))) {
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, argInfo.typeToken);
|
||||
if ((!argInfo.typeToken->isUnsigned() || !Token::Match(argInfo.typeToken, "char|short|long|int")) && argInfo.typeToken->str() != "bool") {
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
} else if ((specifier[0] == 'l' && (argInfo.typeToken->str() != "long" || (specifier[1] == 'l' && !argInfo.typeToken->isLong()))) ||
|
||||
(specifier.find("I64") != std::string::npos && (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong()))) {
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
} else if ((specifier[0] == 'z' || (specifier[0] == 'I' && specifier[1] == 'u')) && argInfo.typeToken->originalName() != "size_t") {
|
||||
// use %z or %I on size_t
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
} else if (argInfo.typeToken->originalName() == "size_t" && (specifier[0] != 'z' && !(specifier[0] == 'I' && specifier[1] == 'u'))) {
|
||||
// size_t requires %z or %I
|
||||
invalidPrintfArgTypeError_uint(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
}
|
||||
done = true;
|
||||
break;
|
||||
case 'p':
|
||||
if (argInfo.functionInfo && argInfo.typeToken->type() == Token::eType && !argInfo.isArrayOrPointer())
|
||||
invalidPrintfArgTypeError_p(tok, numFormat, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_p(tok, numFormat, &argInfo);
|
||||
else if (argInfo.variableInfo && argInfo.typeToken && argInfo.isKnownType() && !argInfo.isArrayOrPointer())
|
||||
invalidPrintfArgTypeError_p(tok, numFormat, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_p(tok, numFormat, &argInfo);
|
||||
else if (argInfo.typeToken->type() == Token::eString)
|
||||
invalidPrintfArgTypeError_p(tok, numFormat, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_p(tok, numFormat, &argInfo);
|
||||
done = true;
|
||||
break;
|
||||
case 'e':
|
||||
|
@ -639,18 +659,18 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
(argInfo.element && !argInfo.isArrayOrPointer()) ||
|
||||
(specifier[0] == 'l' && (!argInfo.typeToken->isLong() || argInfo.typeToken->str() != "double")) ||
|
||||
(specifier[0] != 'l' && argInfo.typeToken->isLong())) {
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
} else if (argInfo.variableInfo) {
|
||||
if ((argInfo.isKnownType() && !Token::Match(argInfo.typeToken, "float|double")) ||
|
||||
(!argInfo.element && argInfo.isArrayOrPointer()) ||
|
||||
(argInfo.element && !argInfo.isArrayOrPointer())) {
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, &argInfo);
|
||||
}
|
||||
} else if (argInfo.typeToken->type() == Token::eString)
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, &argInfo);
|
||||
else if (!Token::Match(argInfo.typeToken, "float|double"))
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, argInfo.typeToken);
|
||||
invalidPrintfArgTypeError_float(tok, numFormat, specifier, &argInfo);
|
||||
done = true;
|
||||
break;
|
||||
case 'h': // Can be 'hh' (signed char or unsigned char) or 'h' (short int or unsigned short int)
|
||||
|
@ -927,27 +947,15 @@ void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, unsigned int numForm
|
|||
errmsg << "%n in format string (no. " << numFormat << ") requires a pointer to an non-const integer given in the argument list.";
|
||||
reportError(tok, Severity::warning, "invalidPrintfArgType_n", errmsg.str());
|
||||
}
|
||||
void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const Token* type)
|
||||
void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo)
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is \'";
|
||||
if (type) {
|
||||
if (type->type() == Token::eString) {
|
||||
if (type->isLong())
|
||||
errmsg << "const wchar_t *";
|
||||
else
|
||||
errmsg << "const char *";
|
||||
} else {
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
}
|
||||
} else
|
||||
errmsg << "Unknown";
|
||||
errmsg << "\'.";
|
||||
errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is ";
|
||||
argumentType(errmsg, argInfo);
|
||||
errmsg << ".";
|
||||
reportError(tok, Severity::warning, "invalidPrintfArgType_p", errmsg.str());
|
||||
}
|
||||
void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type)
|
||||
void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a";
|
||||
|
@ -956,38 +964,12 @@ void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFo
|
|||
else
|
||||
errmsg << (specifier[0] == 'l' ? " long " : "n ")
|
||||
<< (specifier[0] == 'l' && specifier[1] == 'l' ? "long " : "");
|
||||
errmsg << "integer but the argument type is \'";
|
||||
if (type) {
|
||||
if (type->type() == Token::eString) {
|
||||
if (type->isLong())
|
||||
errmsg << "const wchar_t *";
|
||||
else
|
||||
errmsg << "const char *";
|
||||
} else {
|
||||
if (type->originalName().empty()) {
|
||||
if (type->str() == "const") {
|
||||
errmsg << "const ";
|
||||
type = type->next();
|
||||
}
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
} else {
|
||||
if ((type->originalName() == "__int64" || type->originalName() == "__int32") && type->isUnsigned())
|
||||
errmsg << "unsigned ";
|
||||
errmsg << type->originalName() << " {aka ";
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
errmsg << "}";
|
||||
}
|
||||
}
|
||||
} else
|
||||
errmsg << "Unknown";
|
||||
errmsg << "\'.";
|
||||
errmsg << "integer but the argument type is ";
|
||||
argumentType(errmsg, argInfo);
|
||||
errmsg << ".";
|
||||
reportError(tok, Severity::warning, "invalidPrintfArgType_int", errmsg.str());
|
||||
}
|
||||
void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type)
|
||||
void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires an unsigned ";
|
||||
|
@ -996,38 +978,12 @@ void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numF
|
|||
else
|
||||
errmsg << (specifier[0] == 'l' ? "long " : "")
|
||||
<< (specifier[0] == 'l' && specifier[1] == 'l' ? "long " : "");
|
||||
errmsg << "integer but the argument type is \'";
|
||||
if (type) {
|
||||
if (type->type() == Token::eString) {
|
||||
if (type->isLong())
|
||||
errmsg << "const wchar_t *";
|
||||
else
|
||||
errmsg << "const char *";
|
||||
} else {
|
||||
if (type->originalName().empty()) {
|
||||
if (type->str() == "const") {
|
||||
errmsg << "const ";
|
||||
type = type->next();
|
||||
}
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
} else {
|
||||
if ((type->originalName() == "__int64" || type->originalName() == "__int32") && type->isUnsigned())
|
||||
errmsg << "unsigned ";
|
||||
errmsg << type->originalName() << " {aka ";
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
errmsg << "}";
|
||||
}
|
||||
}
|
||||
} else
|
||||
errmsg << "Unknown";
|
||||
errmsg << "\'.";
|
||||
errmsg << "integer but the argument type is ";
|
||||
argumentType(errmsg, argInfo);
|
||||
errmsg << ".";
|
||||
reportError(tok, Severity::warning, "invalidPrintfArgType_uint", errmsg.str());
|
||||
}
|
||||
void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type)
|
||||
void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a signed ";
|
||||
|
@ -1036,71 +992,56 @@ void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numF
|
|||
else
|
||||
errmsg << (specifier[0] == 'l' ? "long " : "")
|
||||
<< (specifier[0] == 'l' && specifier[1] == 'l' ? "long " : "");
|
||||
errmsg << "integer but the argument type is \'";
|
||||
if (type) {
|
||||
if (type->type() == Token::eString) {
|
||||
if (type->isLong())
|
||||
errmsg << "const wchar_t *";
|
||||
else
|
||||
errmsg << "const char *";
|
||||
} else {
|
||||
if (type->originalName().empty()) {
|
||||
if (type->str() == "const") {
|
||||
errmsg << "const ";
|
||||
type = type->next();
|
||||
}
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
} else {
|
||||
if ((type->originalName() == "__int64" || type->originalName() == "__int32") && type->isUnsigned())
|
||||
errmsg << "unsigned ";
|
||||
errmsg << type->originalName() << " {aka ";
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
errmsg << "}";
|
||||
}
|
||||
}
|
||||
} else
|
||||
errmsg << "Unknown";
|
||||
errmsg << "\'.";
|
||||
errmsg << "integer but the argument type is ";
|
||||
argumentType(errmsg, argInfo);
|
||||
errmsg << ".";
|
||||
reportError(tok, Severity::warning, "invalidPrintfArgType_sint", errmsg.str());
|
||||
}
|
||||
void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type)
|
||||
void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a floating point number but the argument type is \'";
|
||||
if (type) {
|
||||
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a floating point number but the argument type is ";
|
||||
argumentType(errmsg, argInfo);
|
||||
errmsg << ".";
|
||||
reportError(tok, Severity::warning, "invalidPrintfArgType_float", errmsg.str());
|
||||
}
|
||||
|
||||
void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
|
||||
{
|
||||
if (argInfo) {
|
||||
os << "\'";
|
||||
const Token *type = argInfo->typeToken;
|
||||
if (type->type() == Token::eString) {
|
||||
if (type->isLong())
|
||||
errmsg << "const wchar_t *";
|
||||
os << "const wchar_t *";
|
||||
else
|
||||
errmsg << "const char *";
|
||||
os << "const char *";
|
||||
} else {
|
||||
if (type->originalName().empty()) {
|
||||
if (type->str() == "const") {
|
||||
errmsg << "const ";
|
||||
os << "const ";
|
||||
type = type->next();
|
||||
}
|
||||
type->stringify(errmsg, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
type->stringify(os, false, true);
|
||||
if (type->strAt(1) == "*" ||
|
||||
(argInfo->variableInfo && !argInfo->element && argInfo->variableInfo->isArray())) {
|
||||
os << " *";
|
||||
}
|
||||
} else {
|
||||
if ((type->originalName() == "__int64" || type->originalName() == "__int32") && type->isUnsigned())
|
||||
errmsg << "unsigned ";
|
||||
errmsg << type->originalName() << " {aka ";
|
||||
type->stringify(errmsg, false, true);
|
||||
os << "unsigned ";
|
||||
os << type->originalName() << " {aka ";
|
||||
type->stringify(os, false, true);
|
||||
if (type->strAt(1) == "*")
|
||||
errmsg << " *";
|
||||
errmsg << "}";
|
||||
os << " *";
|
||||
os << "}";
|
||||
}
|
||||
}
|
||||
os << "\'";
|
||||
} else
|
||||
errmsg << "Unknown";
|
||||
errmsg << "\'.";
|
||||
reportError(tok, Severity::warning, "invalidPrintfArgType_float", errmsg.str());
|
||||
os << "Unknown";
|
||||
}
|
||||
|
||||
void CheckIO::invalidLengthModifierError(const Token* tok, unsigned int numFormat, const std::string& modifier)
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
|
|
|
@ -90,6 +90,7 @@ private:
|
|||
const Function *functionInfo;
|
||||
bool element;
|
||||
Token *tempToken;
|
||||
|
||||
private:
|
||||
ArgumentInfo(const ArgumentInfo &); // not implemented
|
||||
ArgumentInfo operator = (const ArgumentInfo &); // not implemented
|
||||
|
@ -112,13 +113,14 @@ private:
|
|||
void invalidScanfArgTypeError(const Token* tok, const std::string &functionName, unsigned int numFormat);
|
||||
void invalidPrintfArgTypeError_s(const Token* tok, unsigned int numFormat);
|
||||
void invalidPrintfArgTypeError_n(const Token* tok, unsigned int numFormat);
|
||||
void invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const Token* type);
|
||||
void invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type);
|
||||
void invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type);
|
||||
void invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type);
|
||||
void invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type);
|
||||
void invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo);
|
||||
void invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo);
|
||||
void invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo);
|
||||
void invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo);
|
||||
void invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo);
|
||||
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);
|
||||
void argumentType(std::ostream & s, const ArgumentInfo * argInfo);
|
||||
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
|
||||
CheckIO c(0, settings, errorLogger);
|
||||
|
|
|
@ -620,7 +620,8 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) %s in format string (no. 1) requires a char* given in the argument list.\n"
|
||||
"[test.cpp:4]: (warning) %s in format string (no. 2) requires a char* given in the argument list.\n"
|
||||
"[test.cpp:5]: (warning) %s in format string (no. 1) requires a char* given in the argument list.\n", errout.str());
|
||||
"[test.cpp:5]: (warning) %s in format string (no. 1) requires a char* given in the argument list.\n"
|
||||
"[test.cpp:7]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'char *'.\n", errout.str());
|
||||
|
||||
check("void foo(const int* cpi, const int ci, int i, int* pi, std::string s) {\n"
|
||||
" printf(\"%n\", cpi);\n"
|
||||
|
@ -681,7 +682,9 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'foo'.\n"
|
||||
"[test.cpp:4]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'const char *'.\n"
|
||||
"[test.cpp:5]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'double'.\n"
|
||||
"[test.cpp:6]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'int'.\n", errout.str());
|
||||
"[test.cpp:6]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'int'.\n"
|
||||
"[test.cpp:7]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'int *'.\n"
|
||||
"[test.cpp:9]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'bar *'.\n", errout.str());
|
||||
|
||||
check("class foo {};\n"
|
||||
"void foo(const int* cpi, foo f, bar b, bar* bp, char c) {\n"
|
||||
|
@ -1143,6 +1146,28 @@ private:
|
|||
"[test.cpp:3]: (warning) %d in format string (no. 4) requires a signed integer but the argument type is 'const char *'.\n"
|
||||
"[test.cpp:3]: (warning) %f in format string (no. 5) requires a floating point number but the argument type is 'const char *'.\n", errout.str());
|
||||
|
||||
check("std::vector<int> array;\n"
|
||||
"char * p = 0;\n"
|
||||
"char q[] = \"abc\";\n"
|
||||
"char r[10] = { 0 };\n"
|
||||
"size_t s;\n"
|
||||
"void foo() {\n"
|
||||
" printf(\"%zu %zu\", array.size(), s);\n"
|
||||
" printf(\"%u %u %u\", p, q, r);\n"
|
||||
" printf(\"%u %u\", array.size(), s);\n"
|
||||
" printf(\"%lu %lu\", array.size(), s);\n"
|
||||
" printf(\"%llu %llu\", array.size(), s);\n"
|
||||
"}\n", false, false, Settings::Unix64);
|
||||
ASSERT_EQUALS("[test.cpp:8]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'char *'.\n"
|
||||
"[test.cpp:8]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'char *'.\n"
|
||||
"[test.cpp:8]: (warning) %u in format string (no. 3) requires an unsigned integer but the argument type is 'char *'.\n"
|
||||
"[test.cpp:9]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'size_t {aka unsigned long}'.\n"
|
||||
"[test.cpp:9]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'size_t {aka unsigned long}'.\n"
|
||||
"[test.cpp:10]: (warning) %lu in format string (no. 1) requires an unsigned long integer but the argument type is 'size_t {aka unsigned long}'.\n"
|
||||
"[test.cpp:10]: (warning) %lu in format string (no. 2) requires an unsigned long integer but the argument type is 'size_t {aka unsigned long}'.\n"
|
||||
"[test.cpp:11]: (warning) %llu in format string (no. 1) requires an unsigned long long integer but the argument type is 'size_t {aka unsigned long}'.\n"
|
||||
"[test.cpp:11]: (warning) %llu in format string (no. 2) requires an unsigned long long integer but the argument type is 'size_t {aka unsigned long}'.\n", errout.str());
|
||||
|
||||
}
|
||||
|
||||
void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings
|
||||
|
|
Loading…
Reference in New Issue