CheckIO: add scanf argument type checking. Floating point and integer checking is complete but string checking is incomplete and character checking is missing. Ticket #4099

This commit is contained in:
Robert Reif 2013-09-22 06:56:31 +02:00 committed by Daniel Marjamäki
parent 6eab4abaf2
commit 5c4c397372
4 changed files with 1145 additions and 33 deletions

View File

@ -537,14 +537,294 @@ void CheckIO::checkWrongPrintfScanfArguments()
if (argInfo.typeToken) { if (argInfo.typeToken) {
if (scan) { if (scan) {
if (warning && ((!argInfo.variableInfo->isPointer() && !argInfo.variableInfo->isArray()) || argInfo.typeToken->strAt(-1) == "const")) std::string specifier;
invalidScanfArgTypeError(tok, tok->str(), numFormat); bool done = false;
while (!done) {
if (*i == 's' && argInfo.variableInfo && argInfo.isKnownType() && argInfo.variableInfo->isArray() && (argInfo.variableInfo->dimensions().size() == 1) && argInfo.variableInfo->dimensions()[0].known) { switch (*i) {
if (!width.empty()) { case 's':
int numWidth = std::atoi(width.c_str()); specifier += *i;
if (numWidth != (argInfo.variableInfo->dimension(0) - 1)) if (argInfo.variableInfo && argInfo.isKnownType() && argInfo.variableInfo->isArray() && (argInfo.variableInfo->dimensions().size() == 1) && argInfo.variableInfo->dimensions()[0].known) {
invalidScanfFormatWidthError(tok, numFormat, numWidth, argInfo.variableInfo); if (!width.empty()) {
int numWidth = std::atoi(width.c_str());
if (numWidth != (argInfo.variableInfo->dimension(0) - 1))
invalidScanfFormatWidthError(tok, numFormat, numWidth, argInfo.variableInfo);
}
}
if (argListTok->type() != Token::eString &&
argInfo.isKnownType() && argInfo.isArrayOrPointer() &&
(!Token::Match(argInfo.typeToken, "char|wchar_t") ||
argInfo.typeToken->strAt(-1) == "const")) {
invalidScanfArgTypeError_s(tok, numFormat, specifier, &argInfo);
}
done = true;
break;
case 'x':
case 'X':
case 'o':
specifier += *i;
if (argInfo.typeToken->type() == Token::eString)
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.isKnownType()) {
if (!argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else {
switch (specifier[0]) {
case 'h':
if (specifier[1] == 'h') {
if (argInfo.typeToken->str() != "char")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
} else if (argInfo.typeToken->str() != "short")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'l':
if (specifier[1] == 'l') {
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.typeToken->originalName() == "size_t" ||
argInfo.typeToken->originalName() == "ptrdiff_t" ||
argInfo.typeToken->originalName() == "intmax_t" ||
argInfo.typeToken->originalName() == "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
} else if (argInfo.typeToken->str() != "long" || argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.typeToken->originalName() == "size_t" ||
argInfo.typeToken->originalName() == "ptrdiff_t" ||
argInfo.typeToken->originalName() == "intmax_t" ||
argInfo.typeToken->originalName() == "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'I':
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'j':
if (argInfo.typeToken->originalName() != "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'z':
if (argInfo.typeToken->originalName() != "size_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 't':
if (argInfo.typeToken->originalName() != "ptrdiff_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'L':
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
default:
if (argInfo.typeToken->str() != "int")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.typeToken->originalName() == "size_t" ||
argInfo.typeToken->originalName() == "ptrdiff_t" ||
argInfo.typeToken->originalName() == "intmax_t" ||
argInfo.typeToken->originalName() == "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
}
}
}
done = true;
break;
case 'n':
case 'd':
case 'i':
specifier += *i;
if (argInfo.typeToken->type() == Token::eString)
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
else if (argInfo.isKnownType()) {
if (argInfo.typeToken->isUnsigned() || !argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
else {
switch (specifier[0]) {
case 'h':
if (specifier[1] == 'h') {
if (argInfo.typeToken->str() != "char")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
} else if (argInfo.typeToken->str() != "short")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
case 'l':
if (specifier[1] == 'l') {
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
else if (argInfo.typeToken->originalName() == "ptrdiff_t" ||
argInfo.typeToken->originalName() == "intmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
} else if (argInfo.typeToken->str() != "long" || argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
else if (argInfo.typeToken->originalName() == "ptrdiff_t" ||
argInfo.typeToken->originalName() == "intmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
case 'I':
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
case 'j':
if (argInfo.typeToken->originalName() != "intmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
case 'z':
if (argInfo.typeToken->originalName() != "size_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
case 't':
if (argInfo.typeToken->originalName() != "ptrdiff_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
case 'L':
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
default:
if (argInfo.typeToken->str() != "int")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
else if (argInfo.typeToken->originalName() == "ptrdiff_t" ||
argInfo.typeToken->originalName() == "intmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, false);
break;
}
}
}
done = true;
break;
case 'u':
specifier += *i;
if (argInfo.typeToken->type() == Token::eString)
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.isKnownType()) {
if (!argInfo.typeToken->isUnsigned() || !argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else {
switch (specifier[0]) {
case 'h':
if (specifier[1] == 'h') {
if (argInfo.typeToken->str() != "char")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
} else if (argInfo.typeToken->str() != "short")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'l':
if (specifier[1] == 'l') {
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.typeToken->originalName() == "size_t" ||
argInfo.typeToken->originalName() == "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
} else if (argInfo.typeToken->str() != "long" || argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.typeToken->originalName() == "size_t" ||
argInfo.typeToken->originalName() == "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'I':
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'j':
if (argInfo.typeToken->originalName() != "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'z':
if (argInfo.typeToken->originalName() != "size_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 't':
if (argInfo.typeToken->originalName() != "ptrdiff_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
case 'L':
if (argInfo.typeToken->str() != "long" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
default:
if (argInfo.typeToken->str() != "int")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
else if (argInfo.typeToken->originalName() == "size_t" ||
argInfo.typeToken->originalName() == "uintmax_t")
invalidScanfArgTypeError_int(tok, numFormat, specifier, &argInfo, true);
break;
}
}
}
done = true;
break;
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
case 'a':
specifier += *i;
if (argInfo.typeToken->type() == Token::eString)
invalidScanfArgTypeError_float(tok, numFormat, specifier, &argInfo);
else if (argInfo.isKnownType()) {
if (!argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")
invalidScanfArgTypeError_float(tok, numFormat, specifier, &argInfo);
else {
switch (specifier[0]) {
case 'l':
if (specifier[1] == 'l') {
if (argInfo.typeToken->str() != "double" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_float(tok, numFormat, specifier, &argInfo);
} else if (argInfo.typeToken->str() != "double" || argInfo.typeToken->isLong())
invalidScanfArgTypeError_float(tok, numFormat, specifier, &argInfo);
break;
case 'L':
if (argInfo.typeToken->str() != "double" || !argInfo.typeToken->isLong())
invalidScanfArgTypeError_float(tok, numFormat, specifier, &argInfo);
break;
default:
if (argInfo.typeToken->str() != "float")
invalidScanfArgTypeError_float(tok, numFormat, specifier, &argInfo);
break;
}
}
}
done = true;
break;
case 'I':
if (i+1 != formatString.end() && *(i+1) == '6' &&
i+2 != formatString.end() && *(i+2) == '4') {
specifier += *i++;
specifier += *i++;
if ((i+1) != formatString.end() && !isalpha(*(i+1))) {
specifier += *i;
invalidLengthModifierError(tok, numFormat, specifier);
done = true;
} else {
specifier += *i++;
}
} else {
specifier += *i;
invalidLengthModifierError(tok, numFormat, specifier);
done = true;
}
break;
case 'h':
case 'l':
if (i+1 != formatString.end() && *(i+1) == *i)
specifier += *i++;
// fallthrough
case 'j':
case 'q':
case 't':
case 'z':
case 'L':
// Expect an alphabetical character after these specifiers
if (i != formatString.end() && !isalpha(*(i+1))) {
specifier += *i;
invalidLengthModifierError(tok, numFormat, specifier);
done = true;
} else {
specifier += *i++;
}
break;
default:
done = true;
break;
} }
} }
} else if (!scan && warning) { } else if (!scan && warning) {
@ -560,7 +840,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
break; break;
case 'n': case 'n':
if ((argInfo.variableInfo && argInfo.isKnownType() && (!argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")) || argListTok->type() == Token::eString) if ((argInfo.variableInfo && argInfo.isKnownType() && (!argInfo.isArrayOrPointer() || argInfo.typeToken->strAt(-1) == "const")) || argListTok->type() == Token::eString)
invalidPrintfArgTypeError_n(tok, numFormat); invalidPrintfArgTypeError_n(tok, numFormat, &argInfo);
done = true; done = true;
break; break;
case 'c': case 'c':
@ -762,13 +1042,18 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings)
, functionInfo(0) , functionInfo(0)
, element(false) , element(false)
, _template(false) , _template(false)
, address(false)
, tempToken(0) , tempToken(0)
{ {
if (tok) { if (tok) {
if (tok->type() == Token::eString) { if (tok->type() == Token::eString) {
typeToken = tok; typeToken = tok;
return; return;
} else if (tok->type() == Token::eVariable || tok->type() == Token::eFunction || Token::Match(tok, "%type% ::")) { } else if (tok->str() == "&" || tok->type() == Token::eVariable || tok->type() == Token::eFunction || Token::Match(tok, "%type% ::")) {
if (tok->str() == "&") {
address = true;
tok = tok->next();
}
while (Token::Match(tok, "%type% ::")) while (Token::Match(tok, "%type% ::"))
tok = tok->tokAt(2); tok = tok->tokAt(2);
if (!tok || !(tok->type() == Token::eVariable || tok->type() == Token::eFunction)) if (!tok || !(tok->type() == Token::eVariable || tok->type() == Token::eFunction))
@ -783,6 +1068,8 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings)
const Function * function = varTok->link()->previous()->function(); const Function * function = varTok->link()->previous()->function();
if (function && function->retDef) { if (function && function->retDef) {
typeToken = function->retDef; typeToken = function->retDef;
if (typeToken->str() == "const")
typeToken = typeToken->next();
functionInfo = function; functionInfo = function;
element = true; element = true;
return; return;
@ -793,6 +1080,8 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * tok, const Settings *settings)
const Function * function = tok1->linkAt(-1)->previous()->function(); const Function * function = tok1->linkAt(-1)->previous()->function();
if (function && function->retDef) { if (function && function->retDef) {
typeToken = function->retDef; typeToken = function->retDef;
if (typeToken->str() == "const")
typeToken = typeToken->next();
functionInfo = function; functionInfo = function;
element = false; element = false;
return; return;
@ -925,7 +1214,9 @@ bool CheckIO::ArgumentInfo::isStdContainer(const Token *tok)
bool CheckIO::ArgumentInfo::isArrayOrPointer() const bool CheckIO::ArgumentInfo::isArrayOrPointer() const
{ {
if (variableInfo && !_template) { if (address)
return true;
else if (variableInfo && !_template) {
return variableInfo->isArrayOrPointer(); return variableInfo->isArrayOrPointer();
} else { } else {
const Token *tok = typeToken; const Token *tok = typeToken;
@ -1001,22 +1292,82 @@ void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, cons
reportError(tok, Severity::warning, "wrongPrintfScanfParameterPositionError", errmsg.str()); reportError(tok, Severity::warning, "wrongPrintfScanfParameterPositionError", errmsg.str());
} }
void CheckIO::invalidScanfArgTypeError(const Token* tok, const std::string &functionName, unsigned int numFormat) void CheckIO::invalidScanfArgTypeError_s(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << functionName << " argument no. " << numFormat << ": requires a non-const pointer or array as argument."; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a \'";
reportError(tok, Severity::warning, "invalidScanfArgType", errmsg.str()); if (specifier[0] == 's')
errmsg << "char";
else if (specifier[0] == 'S')
errmsg << "wchar_t";
errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo);
errmsg << ".";
reportError(tok, Severity::warning, "invalidScanfArgType_s", errmsg.str());
} }
void CheckIO::invalidScanfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned)
{
std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'";
if (specifier[0] == 'h') {
if (specifier[1] == 'h')
errmsg << (isUnsigned ? "unsigned " : "") << "char";
else
errmsg << (isUnsigned ? "unsigned " : "") << "short";
} else if (specifier[0] == 'l') {
if (specifier[1] == 'l')
errmsg << (isUnsigned ? "unsigned " : "") << "long long";
else
errmsg << (isUnsigned ? "unsigned " : "") << "long";
} else if (specifier[0] == 'I') {
errmsg << (isUnsigned ? "unsigned " : "") << "__int64";
} else if (specifier[0] == 'j') {
if (isUnsigned)
errmsg << "uintmax_t";
else
errmsg << "intmax_t";
} else if (specifier[0] == 'z') {
errmsg << "size_t";
} else if (specifier[0] == 't') {
errmsg << (isUnsigned ? "unsigned " : "") << "ptrdiff_t";
} else if (specifier[0] == 'L') {
errmsg << (isUnsigned ? "unsigned " : "") << "long long";
} else {
errmsg << (isUnsigned ? "unsigned " : "") << "int";
}
errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo);
errmsg << ".";
reportError(tok, Severity::warning, "invalidScanfArgType_int", errmsg.str());
}
void CheckIO::invalidScanfArgTypeError_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 \'";
if (specifier[0] == 'l' && specifier[1] != 'l')
errmsg << "double";
else if (specifier[0] == 'L')
errmsg << "long double";
else
errmsg << "float";
errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo);
errmsg << ".";
reportError(tok, Severity::warning, "invalidScanfArgType_float", errmsg.str());
}
void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, unsigned int numFormat) void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, unsigned int numFormat)
{ {
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%s in format string (no. " << numFormat << ") requires a char* given in the argument list."; errmsg << "%s in format string (no. " << numFormat << ") requires a char* given in the argument list.";
reportError(tok, Severity::warning, "invalidPrintfArgType_s", errmsg.str()); reportError(tok, Severity::warning, "invalidPrintfArgType_s", errmsg.str());
} }
void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, unsigned int numFormat) void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo)
{ {
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%n in format string (no. " << numFormat << ") requires a pointer to an non-const integer given in the argument list."; errmsg << "%n in format string (no. " << numFormat << ") requires \'int *\' but the argument type is ";
argumentType(errmsg, argInfo);
errmsg << ".";
reportError(tok, Severity::warning, "invalidPrintfArgType_n", errmsg.str()); reportError(tok, Severity::warning, "invalidPrintfArgType_n", errmsg.str());
} }
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)
@ -1093,6 +1444,8 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
os << "const char *"; os << "const char *";
} else { } else {
if (type->originalName().empty()) { if (type->originalName().empty()) {
if (type->strAt(-1) == "const")
os << "const ";
while (Token::Match(type, "const|struct")) { while (Token::Match(type, "const|struct")) {
os << type->str() << " "; os << type->str() << " ";
type = type->next(); type = type->next();
@ -1102,12 +1455,17 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
os << " *"; os << " *";
else if (argInfo->variableInfo && !argInfo->element && argInfo->variableInfo->isArray()) else if (argInfo->variableInfo && !argInfo->element && argInfo->variableInfo->isArray())
os << " *"; os << " *";
if (argInfo->address)
os << " *";
} else { } else {
if ((type->originalName() == "__int64" || type->originalName() == "__int32") && type->isUnsigned()) if ((type->originalName() == "__int64" || type->originalName() == "__int32") && type->isUnsigned())
os << "unsigned "; os << "unsigned ";
os << type->originalName() << " {aka "; os << type->originalName();
if (type->strAt(1) == "*" || argInfo->address)
os << " *";
os << " {aka ";
type->stringify(os, false, true); type->stringify(os, false, true);
if (type->strAt(1) == "*") if (type->strAt(1) == "*" || argInfo->address)
os << " *"; os << " *";
os << "}"; os << "}";
} }

View File

@ -86,6 +86,7 @@ private:
const Function *functionInfo; const Function *functionInfo;
bool element; bool element;
bool _template; bool _template;
bool address;
Token *tempToken; Token *tempToken;
private: private:
@ -107,9 +108,11 @@ private:
unsigned int numFunction); unsigned int numFunction);
void wrongPrintfScanfPosixParameterPositionError(const Token* tok, const std::string& functionName, void wrongPrintfScanfPosixParameterPositionError(const Token* tok, const std::string& functionName,
unsigned int index, unsigned int numFunction); unsigned int index, unsigned int numFunction);
void invalidScanfArgTypeError(const Token* tok, const std::string &functionName, unsigned int numFormat); void invalidScanfArgTypeError_s(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo);
void invalidScanfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned);
void invalidScanfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo);
void invalidPrintfArgTypeError_s(const Token* tok, unsigned int numFormat); void invalidPrintfArgTypeError_s(const Token* tok, unsigned int numFormat);
void invalidPrintfArgTypeError_n(const Token* tok, unsigned int numFormat); void invalidPrintfArgTypeError_n(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo);
void invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const ArgumentInfo* argInfo); 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_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_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const ArgumentInfo* argInfo);
@ -130,9 +133,11 @@ private:
c.useClosedFileError(0); c.useClosedFileError(0);
c.invalidScanfError(0, false); c.invalidScanfError(0, false);
c.wrongPrintfScanfArgumentsError(0,"printf",3,2); c.wrongPrintfScanfArgumentsError(0,"printf",3,2);
c.invalidScanfArgTypeError(0, "scanf", 1); c.invalidScanfArgTypeError_s(0, 1, "s", NULL);
c.invalidScanfArgTypeError_int(0, 1, "d", NULL, false);
c.invalidScanfArgTypeError_float(0, 1, "f", NULL);
c.invalidPrintfArgTypeError_s(0, 1); c.invalidPrintfArgTypeError_s(0, 1);
c.invalidPrintfArgTypeError_n(0, 1); c.invalidPrintfArgTypeError_n(0, 1, NULL);
c.invalidPrintfArgTypeError_p(0, 1, NULL); c.invalidPrintfArgTypeError_p(0, 1, NULL);
c.invalidPrintfArgTypeError_int(0, 1, "X", NULL); c.invalidPrintfArgTypeError_int(0, 1, "X", NULL);
c.invalidPrintfArgTypeError_uint(0, 1, "u", NULL); c.invalidPrintfArgTypeError_uint(0, 1, "u", NULL);

View File

@ -5364,7 +5364,7 @@ void Tokenizer::simplifyPlatformTypes()
tok->deleteThis(); tok->deleteThis();
} }
if (Token::Match(tok, "size_t|uintptr_t")) { if (Token::Match(tok, "size_t|uintptr_t|uintmax_t")) {
if (inStd) if (inStd)
tok->originalName("std::" + tok->str()); tok->originalName("std::" + tok->str());
else else
@ -5383,7 +5383,7 @@ void Tokenizer::simplifyPlatformTypes()
tok->str("int"); tok->str("int");
break; break;
} }
} else if (Token::Match(tok, "ssize_t|ptrdiff_t|intptr_t")) { } else if (Token::Match(tok, "ssize_t|ptrdiff_t|intptr_t|intmax_t")) {
if (inStd) if (inStd)
tok->originalName("std::" + tok->str()); tok->originalName("std::" + tok->str());
else else

View File

@ -552,6 +552,755 @@ private:
" sscanf(input, \"%5s\", output);\n" " sscanf(input, \"%5s\", output);\n"
"}", true); "}", true);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("const unsigned int * foo() { }\n"
"void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, \"str\", L\"str\", foo(), &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:23]: (warning) %u in format string (no. 1) requires 'unsigned int *' but the argument type is 'bool *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 2) requires 'unsigned int *' but the argument type is 'char *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 3) requires 'unsigned int *' but the argument type is 'signed char *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 4) requires 'unsigned int *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 5) requires 'unsigned int *' but the argument type is 'short *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 6) requires 'unsigned int *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 7) requires 'unsigned int *' but the argument type is 'int *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 9) requires 'unsigned int *' but the argument type is 'long *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 10) requires 'unsigned int *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 11) requires 'unsigned int *' but the argument type is 'long long *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 12) requires 'unsigned int *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 13) requires 'unsigned int *' but the argument type is 'float *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 14) requires 'unsigned int *' but the argument type is 'double *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 15) requires 'unsigned int *' but the argument type is 'long double *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 16) requires 'unsigned int *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 17) requires 'unsigned int *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 18) requires 'unsigned int *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 19) requires 'unsigned int *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 20) requires 'unsigned int *' but the argument type is 'void * *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 21) requires 'unsigned int *' but the argument type is 'void *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 22) requires 'unsigned int *' but the argument type is 'const char *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 23) requires 'unsigned int *' but the argument type is 'const wchar_t *'.\n"
"[test.cpp:23]: (warning) %u in format string (no. 24) requires 'unsigned int *' but the argument type is 'const unsigned int *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:22]: (warning) %lu in format string (no. 1) requires 'unsigned long *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 2) requires 'unsigned long *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 3) requires 'unsigned long *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 4) requires 'unsigned long *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 5) requires 'unsigned long *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 6) requires 'unsigned long *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 7) requires 'unsigned long *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 8) requires 'unsigned long *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 9) requires 'unsigned long *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 11) requires 'unsigned long *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 12) requires 'unsigned long *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 13) requires 'unsigned long *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 14) requires 'unsigned long *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 15) requires 'unsigned long *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 16) requires 'unsigned long *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 17) requires 'unsigned long *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 18) requires 'unsigned long *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 19) requires 'unsigned long *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 20) requires 'unsigned long *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %lu in format string (no. 21) requires 'unsigned long *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:22]: (warning) %llu in format string (no. 1) requires 'unsigned long long *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 2) requires 'unsigned long long *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 3) requires 'unsigned long long *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 4) requires 'unsigned long long *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 5) requires 'unsigned long long *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 6) requires 'unsigned long long *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 7) requires 'unsigned long long *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 8) requires 'unsigned long long *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 9) requires 'unsigned long long *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 10) requires 'unsigned long long *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 11) requires 'unsigned long long *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 13) requires 'unsigned long long *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 14) requires 'unsigned long long *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 15) requires 'unsigned long long *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 16) requires 'unsigned long long *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 17) requires 'unsigned long long *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 18) requires 'unsigned long long *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 19) requires 'unsigned long long *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 20) requires 'unsigned long long *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %llu in format string (no. 21) requires 'unsigned long long *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:22]: (warning) %hu in format string (no. 1) requires 'unsigned short *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 2) requires 'unsigned short *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 3) requires 'unsigned short *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 4) requires 'unsigned short *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 5) requires 'unsigned short *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 7) requires 'unsigned short *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 8) requires 'unsigned short *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 9) requires 'unsigned short *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 10) requires 'unsigned short *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 11) requires 'unsigned short *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 12) requires 'unsigned short *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 13) requires 'unsigned short *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 14) requires 'unsigned short *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 15) requires 'unsigned short *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 16) requires 'unsigned short *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 17) requires 'unsigned short *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 18) requires 'unsigned short *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 19) requires 'unsigned short *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 20) requires 'unsigned short *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %hu in format string (no. 21) requires 'unsigned short *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:22]: (warning) %hhu in format string (no. 1) requires 'unsigned char *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 2) requires 'unsigned char *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 3) requires 'unsigned char *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 5) requires 'unsigned char *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 6) requires 'unsigned char *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 7) requires 'unsigned char *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 8) requires 'unsigned char *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 9) requires 'unsigned char *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 10) requires 'unsigned char *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 11) requires 'unsigned char *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 12) requires 'unsigned char *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 13) requires 'unsigned char *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 14) requires 'unsigned char *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 15) requires 'unsigned char *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 16) requires 'unsigned char *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 17) requires 'unsigned char *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 18) requires 'unsigned char *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 19) requires 'unsigned char *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 20) requires 'unsigned char *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %hhu in format string (no. 21) requires 'unsigned char *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:22]: (warning) %Lu in format string (no. 1) requires 'unsigned long long *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 2) requires 'unsigned long long *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 3) requires 'unsigned long long *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 4) requires 'unsigned long long *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 5) requires 'unsigned long long *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 6) requires 'unsigned long long *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 7) requires 'unsigned long long *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 8) requires 'unsigned long long *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 9) requires 'unsigned long long *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 10) requires 'unsigned long long *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 11) requires 'unsigned long long *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 13) requires 'unsigned long long *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 14) requires 'unsigned long long *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 15) requires 'unsigned long long *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 16) requires 'unsigned long long *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 17) requires 'unsigned long long *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 18) requires 'unsigned long long *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 19) requires 'unsigned long long *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 20) requires 'unsigned long long *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %Lu in format string (no. 21) requires 'unsigned long long *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:22]: (warning) %ju in format string (no. 1) requires 'uintmax_t *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 2) requires 'uintmax_t *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 3) requires 'uintmax_t *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 4) requires 'uintmax_t *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 5) requires 'uintmax_t *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 6) requires 'uintmax_t *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 7) requires 'uintmax_t *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 8) requires 'uintmax_t *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 9) requires 'uintmax_t *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 10) requires 'uintmax_t *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 11) requires 'uintmax_t *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 12) requires 'uintmax_t *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 13) requires 'uintmax_t *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 14) requires 'uintmax_t *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 15) requires 'uintmax_t *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 16) requires 'uintmax_t *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 17) requires 'uintmax_t *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 18) requires 'uintmax_t *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 20) requires 'uintmax_t *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %ju in format string (no. 21) requires 'uintmax_t *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:22]: (warning) %zu in format string (no. 1) requires 'size_t *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 2) requires 'size_t *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 3) requires 'size_t *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 4) requires 'size_t *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 5) requires 'size_t *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 6) requires 'size_t *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 7) requires 'size_t *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 8) requires 'size_t *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 9) requires 'size_t *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 10) requires 'size_t *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 11) requires 'size_t *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 12) requires 'size_t *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 13) requires 'size_t *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 14) requires 'size_t *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 15) requires 'size_t *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 17) requires 'size_t *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 18) requires 'size_t *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 19) requires 'size_t *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 20) requires 'size_t *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %zu in format string (no. 21) requires 'size_t *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu %tu\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", false, false, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:22]: (warning) %tu in format string (no. 1) requires 'unsigned ptrdiff_t *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 2) requires 'unsigned ptrdiff_t *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 3) requires 'unsigned ptrdiff_t *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 4) requires 'unsigned ptrdiff_t *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 5) requires 'unsigned ptrdiff_t *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 6) requires 'unsigned ptrdiff_t *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 7) requires 'unsigned ptrdiff_t *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 8) requires 'unsigned ptrdiff_t *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 9) requires 'unsigned ptrdiff_t *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 10) requires 'unsigned ptrdiff_t *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 11) requires 'unsigned ptrdiff_t *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 12) requires 'unsigned ptrdiff_t *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 13) requires 'unsigned ptrdiff_t *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 14) requires 'unsigned ptrdiff_t *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 15) requires 'unsigned ptrdiff_t *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 16) requires 'unsigned ptrdiff_t *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 17) requires 'unsigned ptrdiff_t *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 18) requires 'unsigned ptrdiff_t *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 19) requires 'unsigned ptrdiff_t *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 20) requires 'unsigned ptrdiff_t *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %tu in format string (no. 21) requires 'unsigned ptrdiff_t *' but the argument type is 'void *'.\n", errout.str());
check("void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u %I64u\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, &unknown, unknown);\n"
"}\n", false, false, Settings::Unix64);
ASSERT_EQUALS("[test.cpp:22]: (warning) %I64u in format string (no. 1) requires 'unsigned __int64 *' but the argument type is 'bool *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 2) requires 'unsigned __int64 *' but the argument type is 'char *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 3) requires 'unsigned __int64 *' but the argument type is 'signed char *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 4) requires 'unsigned __int64 *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 5) requires 'unsigned __int64 *' but the argument type is 'short *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 6) requires 'unsigned __int64 *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 7) requires 'unsigned __int64 *' but the argument type is 'int *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 8) requires 'unsigned __int64 *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 9) requires 'unsigned __int64 *' but the argument type is 'long *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 10) requires 'unsigned __int64 *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 11) requires 'unsigned __int64 *' but the argument type is 'long long *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 13) requires 'unsigned __int64 *' but the argument type is 'float *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 14) requires 'unsigned __int64 *' but the argument type is 'double *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 15) requires 'unsigned __int64 *' but the argument type is 'long double *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 16) requires 'unsigned __int64 *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 17) requires 'unsigned __int64 *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 18) requires 'unsigned __int64 *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 19) requires 'unsigned __int64 *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 20) requires 'unsigned __int64 *' but the argument type is 'void * *'.\n"
"[test.cpp:22]: (warning) %I64u in format string (no. 21) requires 'unsigned __int64 *' but the argument type is 'void *'.\n", errout.str());
check("const int * foo() { }\n"
"void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, \"str\", L\"str\", foo(), &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:23]: (warning) %d in format string (no. 1) requires 'int *' but the argument type is 'bool *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 2) requires 'int *' but the argument type is 'char *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 3) requires 'int *' but the argument type is 'signed char *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 4) requires 'int *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 5) requires 'int *' but the argument type is 'short *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 6) requires 'int *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 8) requires 'int *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 9) requires 'int *' but the argument type is 'long *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 10) requires 'int *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 11) requires 'int *' but the argument type is 'long long *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 12) requires 'int *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 13) requires 'int *' but the argument type is 'float *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 14) requires 'int *' but the argument type is 'double *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 15) requires 'int *' but the argument type is 'long double *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 16) requires 'int *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 17) requires 'int *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 18) requires 'int *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 19) requires 'int *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 20) requires 'int *' but the argument type is 'void * *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 21) requires 'int *' but the argument type is 'void *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 22) requires 'int *' but the argument type is 'const char *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 23) requires 'int *' but the argument type is 'const wchar_t *'.\n"
"[test.cpp:23]: (warning) %d in format string (no. 24) requires 'int *' but the argument type is 'const int *'.\n", errout.str());
check("const unsigned int * foo() { }\n"
"void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, \"str\", L\"str\", foo(), &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:23]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'bool *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 2) requires 'unsigned int *' but the argument type is 'char *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 3) requires 'unsigned int *' but the argument type is 'signed char *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 4) requires 'unsigned int *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 5) requires 'unsigned int *' but the argument type is 'short *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 6) requires 'unsigned int *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 9) requires 'unsigned int *' but the argument type is 'long *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 10) requires 'unsigned int *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 11) requires 'unsigned int *' but the argument type is 'long long *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 12) requires 'unsigned int *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 13) requires 'unsigned int *' but the argument type is 'float *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 14) requires 'unsigned int *' but the argument type is 'double *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 15) requires 'unsigned int *' but the argument type is 'long double *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 16) requires 'unsigned int *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 17) requires 'unsigned int *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 18) requires 'unsigned int *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 19) requires 'unsigned int *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 20) requires 'unsigned int *' but the argument type is 'void * *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 21) requires 'unsigned int *' but the argument type is 'void *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 22) requires 'unsigned int *' but the argument type is 'const char *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 23) requires 'unsigned int *' but the argument type is 'const wchar_t *'.\n"
"[test.cpp:23]: (warning) %x in format string (no. 24) requires 'unsigned int *' but the argument type is 'const unsigned int *'.\n", errout.str());
check("const float * foo() { }\n"
"void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, \"str\", L\"str\", foo(), &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:23]: (warning) %f in format string (no. 1) requires 'float *' but the argument type is 'bool *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 2) requires 'float *' but the argument type is 'char *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 3) requires 'float *' but the argument type is 'signed char *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 4) requires 'float *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 5) requires 'float *' but the argument type is 'short *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 6) requires 'float *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 7) requires 'float *' but the argument type is 'int *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 8) requires 'float *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 9) requires 'float *' but the argument type is 'long *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 10) requires 'float *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 11) requires 'float *' but the argument type is 'long long *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 12) requires 'float *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 14) requires 'float *' but the argument type is 'double *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 15) requires 'float *' but the argument type is 'long double *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 16) requires 'float *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 17) requires 'float *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 18) requires 'float *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 19) requires 'float *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 20) requires 'float *' but the argument type is 'void * *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 21) requires 'float *' but the argument type is 'void *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 22) requires 'float *' but the argument type is 'const char *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 23) requires 'float *' but the argument type is 'const wchar_t *'.\n"
"[test.cpp:23]: (warning) %f in format string (no. 24) requires 'float *' but the argument type is 'const float *'.\n", errout.str());
check("const double * foo() { }\n"
"void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, \"str\", L\"str\", foo(), &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:23]: (warning) %lf in format string (no. 1) requires 'double *' but the argument type is 'bool *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 2) requires 'double *' but the argument type is 'char *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 3) requires 'double *' but the argument type is 'signed char *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 4) requires 'double *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 5) requires 'double *' but the argument type is 'short *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 6) requires 'double *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 7) requires 'double *' but the argument type is 'int *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 8) requires 'double *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 9) requires 'double *' but the argument type is 'long *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 10) requires 'double *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 11) requires 'double *' but the argument type is 'long long *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 12) requires 'double *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 13) requires 'double *' but the argument type is 'float *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 15) requires 'double *' but the argument type is 'long double *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 16) requires 'double *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 17) requires 'double *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 18) requires 'double *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 19) requires 'double *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 20) requires 'double *' but the argument type is 'void * *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 21) requires 'double *' but the argument type is 'void *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 22) requires 'double *' but the argument type is 'const char *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 23) requires 'double *' but the argument type is 'const wchar_t *'.\n"
"[test.cpp:23]: (warning) %lf in format string (no. 24) requires 'double *' but the argument type is 'const double *'.\n", errout.str());
check("const long double * foo() { }\n"
"void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, \"str\", L\"str\", foo(), &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:23]: (warning) %Lf in format string (no. 1) requires 'long double *' but the argument type is 'bool *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 2) requires 'long double *' but the argument type is 'char *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 3) requires 'long double *' but the argument type is 'signed char *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 4) requires 'long double *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 5) requires 'long double *' but the argument type is 'short *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 6) requires 'long double *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 7) requires 'long double *' but the argument type is 'int *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 8) requires 'long double *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 9) requires 'long double *' but the argument type is 'long *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 10) requires 'long double *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 11) requires 'long double *' but the argument type is 'long long *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 12) requires 'long double *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 13) requires 'long double *' but the argument type is 'float *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 14) requires 'long double *' but the argument type is 'double *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 16) requires 'long double *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 17) requires 'long double *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 18) requires 'long double *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 19) requires 'long double *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 20) requires 'long double *' but the argument type is 'void * *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 21) requires 'long double *' but the argument type is 'void *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 22) requires 'long double *' but the argument type is 'const char *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 23) requires 'long double *' but the argument type is 'const wchar_t *'.\n"
"[test.cpp:23]: (warning) %Lf in format string (no. 24) requires 'long double *' but the argument type is 'const long double *'.\n", errout.str());
check("const int * foo() { }\n"
"void foo() {\n"
" bool b;\n"
" char c;\n"
" signed char sc;\n"
" unsigned char uc;\n"
" short s;\n"
" unsigned short us;\n"
" int i;\n"
" unsigned int ui;\n"
" long l;\n"
" unsigned long ul;\n"
" long long ll;\n"
" unsigned long long ull;\n"
" float f;\n"
" double d;\n"
" long double ld;\n"
" size_t st;\n"
" ptrdiff_t pt;\n"
" intmax_t it;\n"
" uintmax_t ut;\n"
" void * vp;\n"
" scanf(\"%n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n\",\n"
" &b, &c, &sc, &uc, &s, &us, &i, &ui, &l, &ul, &ll, &ull, &f, &d, &ld, &st, &pt, &it, &ut, &vp, vp, \"str\", L\"str\", foo(), &unknown, unknown);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:23]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'bool *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 2) requires 'int *' but the argument type is 'char *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 3) requires 'int *' but the argument type is 'signed char *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 4) requires 'int *' but the argument type is 'unsigned char *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 5) requires 'int *' but the argument type is 'short *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 6) requires 'int *' but the argument type is 'unsigned short *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 8) requires 'int *' but the argument type is 'unsigned int *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 9) requires 'int *' but the argument type is 'long *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 10) requires 'int *' but the argument type is 'unsigned long *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 11) requires 'int *' but the argument type is 'long long *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 12) requires 'int *' but the argument type is 'unsigned long long *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 13) requires 'int *' but the argument type is 'float *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 14) requires 'int *' but the argument type is 'double *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 15) requires 'int *' but the argument type is 'long double *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 16) requires 'int *' but the argument type is 'size_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 17) requires 'int *' but the argument type is 'ptrdiff_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 18) requires 'int *' but the argument type is 'intmax_t * {aka long *}'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 19) requires 'int *' but the argument type is 'uintmax_t * {aka unsigned long *}'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 20) requires 'int *' but the argument type is 'void * *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 21) requires 'int *' but the argument type is 'void *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 22) requires 'int *' but the argument type is 'const char *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 23) requires 'int *' but the argument type is 'const wchar_t *'.\n"
"[test.cpp:23]: (warning) %n in format string (no. 24) requires 'int *' but the argument type is 'const int *'.\n", errout.str());
} }
void testPrintfArgument() { void testPrintfArgument() {
@ -631,11 +1380,11 @@ private:
" printf(\"%n\", s);\n" " printf(\"%n\", s);\n"
" printf(\"%n\", \"s4\");\n" " printf(\"%n\", \"s4\");\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (warning) %n in format string (no. 1) requires a pointer to an non-const integer given in the argument list.\n" ASSERT_EQUALS("[test.cpp:2]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'const int *'.\n"
"[test.cpp:3]: (warning) %n in format string (no. 1) requires a pointer to an non-const integer given in the argument list.\n" "[test.cpp:3]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'const int'.\n"
"[test.cpp:4]: (warning) %n in format string (no. 1) requires a pointer to an non-const integer given in the argument list.\n" "[test.cpp:4]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'int'.\n"
"[test.cpp:6]: (warning) %n in format string (no. 1) requires a pointer to an non-const integer given in the argument list.\n" "[test.cpp:6]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'std'.\n"
"[test.cpp:7]: (warning) %n in format string (no. 1) requires a pointer to an non-const integer given in the argument list.\n", errout.str()); "[test.cpp:7]: (warning) %n in format string (no. 1) requires 'int *' but the argument type is 'const char *'.\n", errout.str());
check("class foo {};\n" check("class foo {};\n"
"void foo(const int* cpi, foo f, bar b, bar* bp, double d, int i, unsigned int u) {\n" "void foo(const int* cpi, foo f, bar b, bar* bp, double d, int i, unsigned int u) {\n"
@ -651,7 +1400,7 @@ private:
ASSERT_EQUALS("[test.cpp:3]: (warning) %X in format string (no. 1) requires an integer but the argument type is 'foo'.\n" ASSERT_EQUALS("[test.cpp:3]: (warning) %X in format string (no. 1) requires an integer but the argument type is 'foo'.\n"
"[test.cpp:4]: (warning) %c in format string (no. 1) requires an integer but the argument type is 'const char *'.\n" "[test.cpp:4]: (warning) %c in format string (no. 1) requires an integer but the argument type is 'const char *'.\n"
"[test.cpp:5]: (warning) %o in format string (no. 1) requires an integer but the argument type is 'double'.\n" "[test.cpp:5]: (warning) %o in format string (no. 1) requires an integer but the argument type is 'double'.\n"
"[test.cpp:6]: (warning) %x in format string (no. 1) requires an integer but the argument type is 'int *'.\n" "[test.cpp:6]: (warning) %x in format string (no. 1) requires an integer but the argument type is 'const int *'.\n"
"[test.cpp:8]: (warning) %X in format string (no. 1) requires an integer but the argument type is 'bar *'.\n", errout.str()); "[test.cpp:8]: (warning) %X in format string (no. 1) requires an integer but the argument type is 'bar *'.\n", errout.str());
check("class foo {};\n" check("class foo {};\n"
@ -669,7 +1418,7 @@ private:
"[test.cpp:4]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'const char *'.\n" "[test.cpp:4]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'const char *'.\n"
"[test.cpp:5]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'double'.\n" "[test.cpp:5]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'double'.\n"
"[test.cpp:6]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'unsigned int'.\n" "[test.cpp:6]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'unsigned int'.\n"
"[test.cpp:7]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'int *'.\n" "[test.cpp:7]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'const int *'.\n"
"[test.cpp:9]: (warning) %i in format string (no. 1) requires a signed integer but the argument type is 'bar *'.\n", errout.str()); "[test.cpp:9]: (warning) %i in format string (no. 1) requires a signed integer but the argument type is 'bar *'.\n", errout.str());
check("class foo {};\n" check("class foo {};\n"
@ -687,7 +1436,7 @@ private:
"[test.cpp:4]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'const char *'.\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: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" "[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:7]: (warning) %u in format string (no. 1) requires an unsigned integer but the argument type is 'const 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()); "[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" check("class foo {};\n"
@ -713,7 +1462,7 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires a 'double' but the argument type is 'foo'.\n" ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires a 'double' but the argument type is 'foo'.\n"
"[test.cpp:4]: (warning) %E in format string (no. 1) requires a 'double' but the argument type is 'const char *'.\n" "[test.cpp:4]: (warning) %E in format string (no. 1) requires a 'double' but the argument type is 'const char *'.\n"
"[test.cpp:5]: (warning) %f in format string (no. 1) requires a 'double' but the argument type is 'int *'.\n" "[test.cpp:5]: (warning) %f in format string (no. 1) requires a 'double' but the argument type is 'const int *'.\n"
"[test.cpp:6]: (warning) %G in format string (no. 1) requires a 'double' but the argument type is 'bar *'.\n", errout.str()); "[test.cpp:6]: (warning) %G in format string (no. 1) requires a 'double' but the argument type is 'bar *'.\n", errout.str());
check("class foo;\n" check("class foo;\n"