From 05f2f0e419231c980e3c9982caa87ea2a2615fe0 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 31 Aug 2013 06:26:39 +0200 Subject: [PATCH] CheckIO: improved type info - keep track of original typename. --- lib/checkio.cpp | 220 +++++++++++++++++------ lib/checkio.h | 20 +-- lib/token.cpp | 9 +- lib/token.h | 18 ++ lib/tokenize.cpp | 75 ++++++-- test/testio.cpp | 398 +++++++++++++++++++++++------------------- test/testtokenize.cpp | 10 +- 7 files changed, 482 insertions(+), 268 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 3a88e9cef..1bd0d474a 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -561,7 +561,7 @@ void CheckIO::checkWrongPrintfScanfArguments() bool element; if (getArgumentInfo(argListTok, &variableInfo, &varTypeTok, &functionInfo, element)) { - if (varTypeTok && varTypeTok->str() == "static") + if (varTypeTok->str() == "static") varTypeTok = varTypeTok->next(); if (scan && varTypeTok) { @@ -586,7 +586,7 @@ void CheckIO::checkWrongPrintfScanfArguments() done = true; break; case 'n': - if ((varTypeTok && isKnownType(variableInfo, varTypeTok) && ((!variableInfo->isPointer() && !variableInfo->isArray()) || varTypeTok->strAt(-1) == "const")) || argListTok->type() == Token::eString) + if ((variableInfo && isKnownType(variableInfo, varTypeTok) && ((!variableInfo->isPointer() && !variableInfo->isArray()) || varTypeTok->strAt(-1) == "const")) || argListTok->type() == Token::eString) invalidPrintfArgTypeError_n(tok, numFormat); done = true; break; @@ -595,69 +595,69 @@ void CheckIO::checkWrongPrintfScanfArguments() case 'X': case 'o': specifier += *i; - if (functionInfo && varTypeTok && ((varTypeTok->isStandardType() || functionInfo->retType) && varTypeTok->next()->str() != "*")) { + if (functionInfo && ((varTypeTok->isStandardType() || functionInfo->retType) && varTypeTok->next()->str() != "*")) { if (!Token::Match(varTypeTok, "bool|short|long|int|char|size_t") || (specifier[0] == 'l' && (varTypeTok->str() != "long" || (specifier[1] == 'l' && !varTypeTok->isLong()))) || (specifier.find("I64") != std::string::npos && (varTypeTok->str() != "long" || !varTypeTok->isLong()))) { - invalidPrintfArgTypeError_int(tok, numFormat, specifier); + invalidPrintfArgTypeError_int(tok, numFormat, specifier, varTypeTok); } - } else if (variableInfo && varTypeTok && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray()) { + } else if (variableInfo && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray()) { if (!Token::Match(varTypeTok, "bool|short|long|int|char|size_t") || (specifier[0] == 'l' && (varTypeTok->str() != "long" || (specifier[1] == 'l' && !varTypeTok->isLong()))) || (specifier.find("I64") != std::string::npos && (varTypeTok->str() != "long" || !varTypeTok->isLong()))) { - invalidPrintfArgTypeError_int(tok, numFormat, specifier); + invalidPrintfArgTypeError_int(tok, numFormat, specifier, varTypeTok); } - } else if (argListTok->type() == Token::eString) { - invalidPrintfArgTypeError_int(tok, numFormat, specifier); + } else if (varTypeTok->type() == Token::eString) { + invalidPrintfArgTypeError_int(tok, numFormat, specifier, varTypeTok); } done = true; break; case 'd': case 'i': specifier += *i; - if (functionInfo && varTypeTok && (varTypeTok->isStandardType() || functionInfo->retType) && varTypeTok->next()->str() != "*") { + if (functionInfo && (varTypeTok->isStandardType() || functionInfo->retType) && varTypeTok->next()->str() != "*") { if (((varTypeTok->isUnsigned() || !Token::Match(varTypeTok, "bool|short|long|int")) && varTypeTok->str() != "char") || (specifier[0] == 'l' && (varTypeTok->str() != "long" || (specifier[1] == 'l' && !varTypeTok->isLong()))) || (specifier.find("I64") != std::string::npos && (varTypeTok->str() != "long" || !varTypeTok->isLong()))) { - invalidPrintfArgTypeError_sint(tok, numFormat, specifier); + invalidPrintfArgTypeError_sint(tok, numFormat, specifier, varTypeTok); } - } else if (variableInfo && varTypeTok && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray()) { + } else if (variableInfo && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray()) { if (((varTypeTok->isUnsigned() || !Token::Match(varTypeTok, "bool|short|long|int")) && varTypeTok->str() != "char") || (specifier[0] == 'l' && (varTypeTok->str() != "long" || (specifier[1] == 'l' && !varTypeTok->isLong()))) || (specifier.find("I64") != std::string::npos && (varTypeTok->str() != "long" || !varTypeTok->isLong()))) { - invalidPrintfArgTypeError_sint(tok, numFormat, specifier); + invalidPrintfArgTypeError_sint(tok, numFormat, specifier, varTypeTok); } - } else if (argListTok->type() == Token::eString) { - invalidPrintfArgTypeError_sint(tok, numFormat, specifier); + } else if (varTypeTok->type() == Token::eString) { + invalidPrintfArgTypeError_sint(tok, numFormat, specifier, varTypeTok); } done = true; break; case 'u': specifier += *i; - if (functionInfo && varTypeTok && ((varTypeTok->isStandardType() || functionInfo->retType) || varTypeTok->next()->str() != "*")) { + if (functionInfo && ((varTypeTok->isStandardType() || functionInfo->retType) || varTypeTok->next()->str() != "*")) { if (((!varTypeTok->isUnsigned() || !Token::Match(varTypeTok, "char|short|long|int|size_t")) && varTypeTok->str() != "bool") || (specifier[0] == 'l' && (varTypeTok->str() != "long" || (specifier[1] == 'l' && !varTypeTok->isLong()))) || (specifier.find("I64") != std::string::npos && (varTypeTok->str() != "long" || !varTypeTok->isLong()))) { - invalidPrintfArgTypeError_uint(tok, numFormat, specifier); + invalidPrintfArgTypeError_uint(tok, numFormat, specifier, varTypeTok); } - } else if (variableInfo && varTypeTok && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray()) { + } else if (variableInfo && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray()) { if (((!varTypeTok->isUnsigned() || !Token::Match(varTypeTok, "char|short|long|int|size_t")) && varTypeTok->str() != "bool") || (specifier[0] == 'l' && (varTypeTok->str() != "long" || (specifier[1] == 'l' && !varTypeTok->isLong()))) || (specifier.find("I64") != std::string::npos && (varTypeTok->str() != "long" || !varTypeTok->isLong()))) { - invalidPrintfArgTypeError_uint(tok, numFormat, specifier); + invalidPrintfArgTypeError_uint(tok, numFormat, specifier, varTypeTok); } - } else if (argListTok->type() == Token::eString) { - invalidPrintfArgTypeError_uint(tok, numFormat, specifier); + } else if (varTypeTok->type() == Token::eString) { + invalidPrintfArgTypeError_uint(tok, numFormat, specifier, varTypeTok); } done = true; break; case 'p': - if (functionInfo && varTypeTok && varTypeTok->type() == Token::eType && varTypeTok->next()->str() != "*") - invalidPrintfArgTypeError_p(tok, numFormat); + if (functionInfo && varTypeTok->type() == Token::eType && varTypeTok->next()->str() != "*") + invalidPrintfArgTypeError_p(tok, numFormat, varTypeTok); else if (variableInfo && varTypeTok && isKnownType(variableInfo, varTypeTok) && !variableInfo->isPointer() && !variableInfo->isArray()) - invalidPrintfArgTypeError_p(tok, numFormat); - else if (argListTok->type() == Token::eString) - invalidPrintfArgTypeError_p(tok, numFormat); + invalidPrintfArgTypeError_p(tok, numFormat, varTypeTok); + else if (varTypeTok->type() == Token::eString) + invalidPrintfArgTypeError_p(tok, numFormat, varTypeTok); done = true; break; case 'e': @@ -666,18 +666,18 @@ void CheckIO::checkWrongPrintfScanfArguments() case 'g': case 'G': specifier += *i; - if (functionInfo && varTypeTok && (((varTypeTok->isStandardType() || functionInfo->retType) && !Token::Match(varTypeTok, "float|double")) || - (!element && Token::simpleMatch(varTypeTok->next(), "*")) || - (element && !Token::simpleMatch(varTypeTok->next(), "*")) || - (specifier[0] == 'l' && (!varTypeTok->isLong() || varTypeTok->str() != "double")) || - (specifier[0] != 'l' && varTypeTok->isLong()))) - invalidPrintfArgTypeError_float(tok, numFormat, specifier); - else if (variableInfo && varTypeTok && ((isKnownType(variableInfo, varTypeTok) && !Token::Match(varTypeTok, "float|double")) || - (!element && variableInfo->isArrayOrPointer()) || - (element && !variableInfo->isArrayOrPointer()))) - invalidPrintfArgTypeError_float(tok, numFormat, specifier); - else if (argListTok->type() == Token::eString) - invalidPrintfArgTypeError_float(tok, numFormat, specifier); + if (functionInfo && (((varTypeTok->isStandardType() || functionInfo->retType) && !Token::Match(varTypeTok, "float|double")) || + (!element && Token::simpleMatch(varTypeTok->next(), "*")) || + (element && !Token::simpleMatch(varTypeTok->next(), "*")) || + (specifier[0] == 'l' && (!varTypeTok->isLong() || varTypeTok->str() != "double")) || + (specifier[0] != 'l' && varTypeTok->isLong()))) + invalidPrintfArgTypeError_float(tok, numFormat, specifier, varTypeTok); + else if (variableInfo && ((isKnownType(variableInfo, varTypeTok) && !Token::Match(varTypeTok, "float|double")) || + (!element && variableInfo->isArrayOrPointer()) || + (element && !variableInfo->isArrayOrPointer()))) + invalidPrintfArgTypeError_float(tok, numFormat, specifier, varTypeTok); + else if (varTypeTok->type() == Token::eString) + invalidPrintfArgTypeError_float(tok, numFormat, specifier, varTypeTok); done = true; break; case 'h': // Can be 'hh' (signed char or unsigned char) or 'h' (short int or unsigned short int) @@ -775,7 +775,7 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok if (tok) { if (tok->type() == Token::eString) { *var = 0; - *typeTok = 0; + *typeTok = tok; *func = 0; element = false; return true; @@ -824,6 +824,7 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok const Variable *variableInfo = varTok->variable(); *var = variableInfo; element = tok1->previous()->str() == "]"; + *func = 0; // look for std::vector operator [] and use template type as return type if (variableInfo) { @@ -833,9 +834,8 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok } else *typeTok = variableInfo->typeStartToken(); } else - *typeTok = NULL; + return false; - *func = 0; return true; } } @@ -896,23 +896,63 @@ 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) +void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, unsigned int numFormat, const Token* type) { std::ostringstream errmsg; - errmsg << "%p in format string (no. " << numFormat << ") requires an address given in the argument list."; + 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 << "\'."; reportError(tok, Severity::warning, "invalidPrintfArgType_p", errmsg.str()); } -void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier) +void CheckIO::invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type) { std::ostringstream errmsg; - errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a" - << (specifier[0] != 'l' ? "n" : "") - << (specifier[0] == 'l' ? " long" : "") - << (specifier[0] == 'l' && specifier[1] == 'l' ? " long" : "") - << " integer given in the argument list."; + errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a"; + if (specifier.find("I64") != std::string::npos) + errmsg << " long long "; + 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()) { + 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 << "\'."; reportError(tok, Severity::warning, "invalidPrintfArgType_int", errmsg.str()); } -void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier) +void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type) { std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires an unsigned "; @@ -921,10 +961,34 @@ 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 given in the argument list."; + 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()) { + 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 << "\'."; reportError(tok, Severity::warning, "invalidPrintfArgType_uint", errmsg.str()); } -void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier) +void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type) { std::ostringstream errmsg; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a signed "; @@ -933,13 +997,61 @@ 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 given in the argument list."; + 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()) { + 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 << "\'."; reportError(tok, Severity::warning, "invalidPrintfArgType_sint", errmsg.str()); } -void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier) +void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier, const Token* type) { std::ostringstream errmsg; - errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a floating point number given in the argument list."; + errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a floating point number 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()) { + 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 << "\'."; reportError(tok, Severity::warning, "invalidPrintfArgType_float", errmsg.str()); } void CheckIO::invalidLengthModifierError(const Token* tok, unsigned int numFormat, const std::string& modifier) diff --git a/lib/checkio.h b/lib/checkio.h index fe4c04742..6c4ac6b80 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -89,11 +89,11 @@ 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); - void invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, const std::string& specifier); - void invalidPrintfArgTypeError_uint(const Token* tok, unsigned int numFormat, const std::string& specifier); - void invalidPrintfArgTypeError_sint(const Token* tok, unsigned int numFormat, const std::string& specifier); - void invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, const std::string& specifier); + 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 invalidLengthModifierError(const Token* tok, unsigned int numFormat, const std::string& modifier); void invalidScanfFormatWidthError(const Token* tok, unsigned int numFormat, int width, const Variable *var); @@ -111,11 +111,11 @@ private: c.invalidScanfArgTypeError(0, "scanf", 1); c.invalidPrintfArgTypeError_s(0, 1); c.invalidPrintfArgTypeError_n(0, 1); - c.invalidPrintfArgTypeError_p(0, 1); - c.invalidPrintfArgTypeError_int(0, 1, "X"); - c.invalidPrintfArgTypeError_uint(0, 1, "u"); - c.invalidPrintfArgTypeError_sint(0, 1, "i"); - c.invalidPrintfArgTypeError_float(0, 1, "f"); + c.invalidPrintfArgTypeError_p(0, 1, NULL); + c.invalidPrintfArgTypeError_int(0, 1, "X", NULL); + c.invalidPrintfArgTypeError_uint(0, 1, "u", NULL); + c.invalidPrintfArgTypeError_sint(0, 1, "i", NULL); + c.invalidPrintfArgTypeError_float(0, 1, "f", NULL); c.invalidScanfFormatWidthError(0, 10, 5, NULL); c.wrongPrintfScanfPosixParameterPositionError(0, "printf", 2, 1); } diff --git a/lib/token.cpp b/lib/token.cpp index f6917433b..615dfcfd7 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -226,6 +226,7 @@ void Token::deleteThis() _scope = _previous->_scope; _function = _previous->_function; _variable = _previous->_variable; + _originalName = _previous->_originalName; if (_link) _link->link(this); @@ -991,8 +992,12 @@ void Token::stringify(std::ostream& os, bool varid, bool attributes) const os << "unsigned "; else if (isSigned()) os << "signed "; - if (isLong()) - os << "long "; + if (isLong()) { + if (_type == eString) + os << "L"; + else + os << "long "; + } } if (_str[0] != '\"' || _str.find("\0") == std::string::npos) os << _str; diff --git a/lib/token.h b/lib/token.h index 931555c39..8b78823bf 100644 --- a/lib/token.h +++ b/lib/token.h @@ -557,6 +557,20 @@ public: const Token* findClosingBracket() const; Token* findClosingBracket(); + /** + * Returns the original name. + */ + const std::string & originalName() const { + return _originalName; + } + + /** + * Sets the original name. + */ + void originalName(const std::string & name) { + _originalName = name; + } + private: void next(Token *nextToken) { _next = nextToken; @@ -630,6 +644,10 @@ private: Token *_astOperand1; Token *_astOperand2; Token *_astParent; + + // original name like size_t + std::string _originalName; + public: void astOperand1(Token *tok); void astOperand2(Token *tok); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8b413fcfe..6cbfd8edb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5341,9 +5341,12 @@ void Tokenizer::simplifyPlatformTypes() enum { isLongLong, isLong, isInt } type; /** @todo This assumes a flat address space. Not true for segmented address space (FAR *). */ - if (_settings->sizeof_size_t == 8) - type = isLongLong; - else if (_settings->sizeof_size_t == 4 && _settings->sizeof_long == 4) + if (_settings->sizeof_size_t == 8) { + if (_settings->sizeof_long == 8) + type = isLong; + else + type = isLongLong; + } else if (_settings->sizeof_size_t == 4 && _settings->sizeof_long == 4) type = isLong; else if (_settings->sizeof_size_t == 4) type = isInt; @@ -5351,7 +5354,9 @@ void Tokenizer::simplifyPlatformTypes() return; for (Token *tok = list.front(); tok; tok = tok->next()) { + bool inStd = false; if (Token::Match(tok, "std :: size_t|ssize_t|ptrdiff_t|intptr_t|uintptr_t")) { + inStd = true; tok->deleteNext(); tok->deleteThis(); } else if (Token::Match(tok, ":: size_t|ssize_t|ptrdiff_t|intptr_t|uintptr_t")) { @@ -5359,6 +5364,10 @@ void Tokenizer::simplifyPlatformTypes() } if (Token::Match(tok, "size_t|uintptr_t")) { + if (inStd) + tok->originalName("std::" + tok->str()); + else + tok->originalName(tok->str()); tok->isUnsigned(true); switch (type) { @@ -5374,6 +5383,10 @@ void Tokenizer::simplifyPlatformTypes() break; } } else if (Token::Match(tok, "ssize_t|ptrdiff_t|intptr_t")) { + if (inStd) + tok->originalName("std::" + tok->str()); + else + tok->originalName(tok->str()); switch (type) { case isLongLong: tok->isLong(true); @@ -5393,29 +5406,41 @@ void Tokenizer::simplifyPlatformTypes() _settings->platformType == Settings::Win32W || _settings->platformType == Settings::Win64) { for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "BOOL|INT|INT32|HFILE|LONG32")) + if (Token::Match(tok, "BOOL|INT|INT32|HFILE|LONG32")) { + tok->originalName(tok->str()); tok->str("int"); - else if (Token::Match(tok, "BOOLEAN|BYTE|UCHAR")) { + } else if (Token::Match(tok, "BOOLEAN|BYTE|UCHAR")) { + tok->originalName(tok->str()); tok->str("char"); tok->isUnsigned(true); - } else if (tok->str() == "CHAR") + } else if (tok->str() == "CHAR") { + tok->originalName(tok->str()); tok->str("char"); - else if (Token::Match(tok, "DWORD|ULONG|COLORREF|LCID|LCTYPE|LGRPID")) { + } else if (Token::Match(tok, "DWORD|ULONG|COLORREF|LCID|LCTYPE|LGRPID")) { tok->str("long"); tok->isUnsigned(true); } else if (Token::Match(tok, "DWORD_PTR|ULONG_PTR|SIZE_T")) { + tok->originalName(tok->str()); tok->str("long"); tok->isUnsigned(true); if (_settings->platformType == Settings::Win64) tok->isLong(true); - } else if (tok->str() == "FLOAT") + } else if (tok->str() == "FLOAT") { + tok->originalName(tok->str()); tok->str("float"); - else if (Token::Match(tok, "HRESULT|LONG")) + } else if (Token::Match(tok, "HRESULT|LONG")) { + tok->originalName(tok->str()); tok->str("long"); - else if (Token::Match(tok, "INT64|LONG64")) { + } else if (Token::Match(tok, "INT8")) { + tok->originalName(tok->str()); + tok->str("char"); + tok->isSigned(true); + } else if (Token::Match(tok, "INT64|LONG64|LONGLONG")) { + tok->originalName(tok->str()); tok->str("long"); - tok->insertToken("long"); + tok->isLong(true); } else if (Token::Match(tok, "LONG_PTR|LPARAM|LRESULT|SSIZE_T")) { + tok->originalName(tok->str()); tok->str("long"); if (_settings->platformType == Settings::Win64) tok->isLong(true); @@ -5461,12 +5486,15 @@ void Tokenizer::simplifyPlatformTypes() tok->isUnsigned(true); tok->str("short"); tok->insertToken("*"); - } else if (tok->str() == "SHORT") + } else if (Token::Match(tok, "SHORT|INT16")) { + tok->originalName(tok->str()); tok->str("short"); - else if (Token::Match(tok, "UINT|MMRESULT|SOCKET|ULONG32|UINT32|DWORD32")) { + } else if (Token::Match(tok, "UINT|MMRESULT|SOCKET|ULONG32|UINT32|DWORD32")) { + tok->originalName(tok->str()); tok->isUnsigned(true); tok->str("int"); } else if (Token::Match(tok, "UINT_PTR|WPARAM")) { + tok->originalName(tok->str()); tok->isUnsigned(true); if (_settings->platformType == Settings::Win64) { tok->str("long"); @@ -5475,17 +5503,21 @@ void Tokenizer::simplifyPlatformTypes() tok->str("int"); } } else if (Token::Match(tok, "USHORT|WORD|ATOM|LANGID")) { + tok->originalName(tok->str()); tok->isUnsigned(true); tok->str("short"); - } else if (tok->str() == "VOID") + } else if (tok->str() == "VOID") { + tok->originalName(tok->str()); tok->str("void"); - else if (tok->str() == "TCHAR") { + } else if (tok->str() == "TCHAR") { + tok->originalName(tok->str()); if (_settings->platformType == Settings::Win32A) tok->str("char"); else { tok->str("wchar_t"); } } else if (tok->str() == "TBYTE") { + tok->originalName(tok->str()); tok->isUnsigned(true); if (_settings->platformType == Settings::Win32A) tok->str("short"); @@ -5509,6 +5541,7 @@ void Tokenizer::simplifyPlatformTypes() tok->insertToken("wchar_t"); } } else if (Token::Match(tok, "ULONG64|DWORD64|ULONGLONG")) { + tok->originalName(tok->str()); tok->isUnsigned(true); tok->isLong(true); tok->str("long"); @@ -5563,13 +5596,17 @@ void Tokenizer::simplifyStdType() tok->isSigned(!isUnsigned); } - if (tok->str() == "__int8") + if (tok->str() == "__int8") { + tok->originalName(tok->str()); tok->str("char"); - else if (tok->str() == "__int16") + } else if (tok->str() == "__int16") { + tok->originalName(tok->str()); tok->str("short"); - else if (tok->str() == "__int32") + } else if (tok->str() == "__int32") { + tok->originalName(tok->str()); tok->str("int"); - else if (tok->str() == "__int64") { + } else if (tok->str() == "__int64") { + tok->originalName(tok->str()); tok->str("long"); tok->isLong(true); } else if (tok->str() == "int") { diff --git a/test/testio.cpp b/test/testio.cpp index 0184e8997..86c002463 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -647,9 +647,9 @@ private: " printf(\"%X\", u);\n" " printf(\"%X\", i);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %X in format string (no. 1) requires an integer given in the argument list.\n" - "[test.cpp:4]: (warning) %c in format string (no. 1) requires an integer given in the argument list.\n" - "[test.cpp:5]: (warning) %o in format string (no. 1) requires an integer given in the argument list.\n", errout.str()); + 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:5]: (warning) %o in format string (no. 1) requires an integer but the argument type is 'double'.\n", errout.str()); check("class foo {};\n" "void foo(const int* cpi, foo f, bar b, bar* bp, double d, unsigned int u, unsigned char uc) {\n" @@ -662,10 +662,10 @@ private: " printf(\"%i\", bp);\n" " printf(\"%i\", uc);\n" // char is smaller than int, so there shouldn't be a problem "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %i in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:4]: (warning) %d in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:5]: (warning) %d in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:6]: (warning) %d in format string (no. 1) requires a signed integer given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %i in format string (no. 1) requires a signed integer but the argument type is 'foo'.\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:6]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'unsigned int'.\n", errout.str()); check("class foo {};\n" "void foo(const int* cpi, foo f, bar b, bar* bp, double d, int i, bool bo) {\n" @@ -678,10 +678,10 @@ private: " printf(\"%u\", bp);\n" " printf(\"%u\", bo);\n" // bool shouldn't have a negative sign "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n" - "[test.cpp:4]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n" - "[test.cpp:5]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n" - "[test.cpp:6]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n", errout.str()); + 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()); check("class foo {};\n" "void foo(const int* cpi, foo f, bar b, bar* bp, char c) {\n" @@ -691,8 +691,8 @@ private: " printf(\"%p\", cpi);\n" " printf(\"%p\", b);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %p in format string (no. 1) requires an address given in the argument list.\n" - "[test.cpp:4]: (warning) %p in format string (no. 1) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %p in format string (no. 1) requires an address but the argument type is 'foo'.\n" + "[test.cpp:4]: (warning) %p in format string (no. 1) requires an address but the argument type is 'char'.\n", errout.str()); check("class foo {};\n" "void foo(const int* cpi, foo f, bar b, bar* bp, double d) {\n" @@ -704,10 +704,10 @@ private: " printf(\"%f\", b);\n" " printf(\"%f\", (float)cpi);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires a floating point number given in the argument list.\n" - "[test.cpp:4]: (warning) %E in format string (no. 1) requires a floating point number given in the argument list.\n" - "[test.cpp:5]: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.\n" - "[test.cpp:6]: (warning) %G in format string (no. 1) requires a floating point number given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires a floating point number but the argument type is 'foo'.\n" + "[test.cpp:4]: (warning) %E in format string (no. 1) requires a floating point number but the argument type is 'const char *'.\n" + "[test.cpp:5]: (warning) %f in format string (no. 1) requires a floating point number but the argument type is 'int *'.\n" + "[test.cpp:6]: (warning) %G in format string (no. 1) requires a floating point number but the argument type is 'bar *'.\n", errout.str()); check("class foo;\n" "void foo(foo f) {\n" @@ -715,9 +715,9 @@ private: " printf(\"%f\", f);\n" " printf(\"%p\", f);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 1) requires an unsigned integer given in the argument list.\n" - "[test.cpp:4]: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.\n" - "[test.cpp:5]: (warning) %p in format string (no. 1) requires an address given in the argument list.\n", errout.str()); + 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) %f in format string (no. 1) requires a floating point number but the argument type is 'foo'.\n" + "[test.cpp:5]: (warning) %p in format string (no. 1) requires an address but the argument type is 'foo'.\n", errout.str()); // Ticket #4189 (Improve check (printf("%l") not detected)) tests (according to C99 7.19.6.1.7) // False positive tests @@ -767,17 +767,38 @@ private: " printf(\"%ld\", i);\n" " printf(\"%lld\", i);\n" "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:3]: (warning) %hhd in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:4]: (warning) %ld in format string (no. 1) requires a signed long integer given in the argument list.\n" - "[test.cpp:5]: (warning) %lld in format string (no. 1) requires a signed long long integer given in the argument list.\n" , errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %hd in format string (no. 1) requires a signed integer but the argument type is 'unsigned int'.\n" + "[test.cpp:3]: (warning) %hhd in format string (no. 1) requires a signed integer but the argument type is 'unsigned int'.\n" + "[test.cpp:4]: (warning) %ld in format string (no. 1) requires a signed long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:5]: (warning) %lld in format string (no. 1) requires a signed long long integer but the argument type is 'unsigned int'.\n" , errout.str()); check("void foo(size_t s, ptrdiff_t p) {\n" " printf(\"%zd\", s);\n" " printf(\"%tu\", p);\n" - "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:3]: (warning) %tu in format string (no. 1) requires an unsigned integer given in the argument list.\n", errout.str()); + "}", false, false, Settings::Unix32); + ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires a signed integer but the argument type is 'size_t {aka unsigned long}'.\n" + "[test.cpp:3]: (warning) %tu in format string (no. 1) requires an unsigned integer but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str()); + + check("void foo(size_t s, ptrdiff_t p) {\n" + " printf(\"%zd\", s);\n" + " printf(\"%tu\", p);\n" + "}", false, false, Settings::Unix64); + ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires a signed integer but the argument type is 'size_t {aka unsigned long}'.\n" + "[test.cpp:3]: (warning) %tu in format string (no. 1) requires an unsigned integer but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str()); + + check("void foo(size_t s, ptrdiff_t p) {\n" + " printf(\"%zd\", s);\n" + " printf(\"%tu\", p);\n" + "}", false, false, Settings::Win32A); + ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires a signed integer but the argument type is 'size_t {aka unsigned long}'.\n" + "[test.cpp:3]: (warning) %tu in format string (no. 1) requires an unsigned integer but the argument type is 'ptrdiff_t {aka long}'.\n", errout.str()); + + check("void foo(size_t s, ptrdiff_t p) {\n" + " printf(\"%zd\", s);\n" + " printf(\"%tu\", p);\n" + "}", false, false, Settings::Win64); + ASSERT_EQUALS("[test.cpp:2]: (warning) %zd in format string (no. 1) requires a signed integer but the argument type is 'size_t {aka unsigned long long}'.\n" + "[test.cpp:3]: (warning) %tu in format string (no. 1) requires an unsigned integer but the argument type is 'ptrdiff_t {aka long long}'.\n", errout.str()); check("void foo(unsigned int i) {\n" " printf(\"%ld\", i);\n" @@ -787,12 +808,12 @@ private: " printf(\"%lx\", i);\n" " printf(\"%llx\", i);\n" "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %ld in format string (no. 1) requires a signed long integer given in the argument list.\n" - "[test.cpp:3]: (warning) %lld in format string (no. 1) requires a signed long long integer given in the argument list.\n" - "[test.cpp:4]: (warning) %lu in format string (no. 1) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:5]: (warning) %llu in format string (no. 1) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:6]: (warning) %lx in format string (no. 1) requires a long integer given in the argument list.\n" - "[test.cpp:7]: (warning) %llx in format string (no. 1) requires a long long integer given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %ld in format string (no. 1) requires a signed long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:3]: (warning) %lld in format string (no. 1) requires a signed long long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:4]: (warning) %lu in format string (no. 1) requires an unsigned long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:5]: (warning) %llu in format string (no. 1) requires an unsigned long long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:6]: (warning) %lx in format string (no. 1) requires a long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:7]: (warning) %llx in format string (no. 1) requires a long long integer but the argument type is 'unsigned int'.\n", errout.str()); check("class Foo {\n" " double d;\n" @@ -810,155 +831,155 @@ private: " foo->d, foo->bar[0].i, a[0],\n" " f[0].d, f[0].baz.i, f[0].bar[0].i);\n" "}"); - ASSERT_EQUALS("[test.cpp:13]: (warning) %d in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:13]: (warning) %f in format string (no. 2) requires a floating point number given in the argument list.\n" - "[test.cpp:13]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n" - "[test.cpp:13]: (warning) %d in format string (no. 4) requires a signed integer given in the argument list.\n" - "[test.cpp:13]: (warning) %f in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:13]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:13]: (warning) %d in format string (no. 1) requires a signed integer but the argument type is 'double'.\n" + "[test.cpp:13]: (warning) %f in format string (no. 2) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:13]: (warning) %f in format string (no. 3) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:13]: (warning) %d in format string (no. 4) requires a signed integer but the argument type is 'double'.\n" + "[test.cpp:13]: (warning) %f in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:13]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'int'.\n", errout.str()); check("short f() { return 0; }\n" "void foo() { printf(\"%d %u %lu %I64u %I64d %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 5) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'short'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'short'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer but the argument type is 'short'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 5) requires a signed long long integer but the argument type is 'short'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'short'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'short'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'short'.\n", errout.str()); check("unsigned short f() { return 0; }\n" "void foo() { printf(\"%u %d %ld %I64d %I64u %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 5) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'unsigned short'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'unsigned short'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer but the argument type is 'unsigned short'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 5) requires an unsigned long long integer but the argument type is 'unsigned short'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'unsigned short'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'unsigned short'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned short'.\n", errout.str()); check("int f() { return 0; }\n" "void foo() { printf(\"%d %u %lu %I64u %I64d %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 5) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 5) requires a signed long long integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'int'.\n", errout.str()); check("unsigned int f() { return 0; }\n" "void foo() { printf(\"%u %d %ld %I64d %I64u %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 5) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 5) requires an unsigned long long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned int'.\n", errout.str()); check("long f() { return 0; }\n" "void foo() { printf(\"%ld %u %lu %I64u %I64d %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 5) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'long'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'long'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer but the argument type is 'long'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 5) requires a signed long long integer but the argument type is 'long'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'long'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'long'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'long'.\n", errout.str()); check("unsigned long f() { return 0; }\n" "void foo() { printf(\"%lu %d %ld %I64d %I64u %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 5) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'unsigned long'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'unsigned long'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer but the argument type is 'unsigned long'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 5) requires an unsigned long long integer but the argument type is 'unsigned long'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'unsigned long'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'unsigned long'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned long'.\n", errout.str()); check("long long f() { return 0; }\n" "void foo() { printf(\"%lld %u %lu %I64u %I64d %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'long long'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'long long'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 4) requires an unsigned long long integer but the argument type is 'long long'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'long long'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'long long'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'long long'.\n", errout.str()); check("unsigned long long f() { return 0; }\n" "void foo() { printf(\"%llu %d %ld %I64d %I64u %f %lf %p\", f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'unsigned long long'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'unsigned long long'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 4) requires a signed long long integer but the argument type is 'unsigned long long'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 6) requires a floating point number but the argument type is 'unsigned long long'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 7) requires a floating point number but the argument type is 'unsigned long long'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 8) requires an address but the argument type is 'unsigned long long'.\n", errout.str()); check("float f() { return 0; }\n" "void foo() { printf(\"%f %d %ld %u %lu %I64d %I64u %lf %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %u in format string (no. 4) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 5) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 6) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 7) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 8) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'float'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'float'.\n" + "[test.cpp:2]: (warning) %u in format string (no. 4) requires an unsigned integer but the argument type is 'float'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 5) requires an unsigned long integer but the argument type is 'float'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 6) requires a signed long long integer but the argument type is 'float'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 7) requires an unsigned long long integer but the argument type is 'float'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 8) requires a floating point number but the argument type is 'float'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address but the argument type is 'float'.\n", errout.str()); check("double f() { return 0; }\n" "void foo() { printf(\"%f %d %ld %u %lu %I64d %I64u %lf %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %u in format string (no. 4) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 5) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 6) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 7) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 8) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'double'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'double'.\n" + "[test.cpp:2]: (warning) %u in format string (no. 4) requires an unsigned integer but the argument type is 'double'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 5) requires an unsigned long integer but the argument type is 'double'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 6) requires a signed long long integer but the argument type is 'double'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 7) requires an unsigned long long integer but the argument type is 'double'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 8) requires a floating point number but the argument type is 'double'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address but the argument type is 'double'.\n", errout.str()); check("long double f() { return 0; }\n" "void foo() { printf(\"%lf %d %ld %u %lu %I64d %I64u %f %p\", f(), f(), f(), f(), f(), f(), f(), f(), f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %u in format string (no. 4) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 5) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64d in format string (no. 6) requires a signed long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %I64u in format string (no. 7) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 8) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'long double'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'long double'.\n" + "[test.cpp:2]: (warning) %u in format string (no. 4) requires an unsigned integer but the argument type is 'long double'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 5) requires an unsigned long integer but the argument type is 'long double'.\n" + "[test.cpp:2]: (warning) %I64d in format string (no. 6) requires a signed long long integer but the argument type is 'long double'.\n" + "[test.cpp:2]: (warning) %I64u in format string (no. 7) requires an unsigned long long integer but the argument type is 'long double'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 8) requires a floating point number but the argument type is 'long double'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 9) requires an address but the argument type is 'long double'.\n", errout.str()); check("namespace bar { int f() { return 0; } }\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", bar::f(), bar::f(), bar::f(), bar::f(), bar::f(), bar::f()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { int i; } f;\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", f.i, f.i, f.i, f.i, f.i, f.i); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { unsigned int u; } f;\n" "void foo() { printf(\"%u %d %ld %f %lf %p\", f.u, f.u, f.u, f.u, f.u, f.u); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address but the argument type is 'unsigned int'.\n", errout.str()); check("struct Fred { unsigned int ui() { return 0; } } f;\n" "void foo() { printf(\"%u %d %ld %f %lf %p\", f.ui(), f.ui(), f.ui(), f.ui(), f.ui(), f.ui()); }"); - ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer given in the argument list.\n" - "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer given in the argument list.\n" - "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) %d in format string (no. 2) requires a signed integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %ld in format string (no. 3) requires a signed long integer but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'unsigned int'.\n" + "[test.cpp:2]: (warning) %p in format string (no. 6) requires an address but the argument type is 'unsigned int'.\n", errout.str()); // #4975 check("void f(int len, int newline) {\n" @@ -970,56 +991,56 @@ private: check("struct Fred { int i; } f;\n" "struct Fred & bar() { };\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { int i; } f;\n" "const struct Fred & bar() { };\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { int i; } f;\n" "static const struct Fred & bar() { };\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", bar().i, bar().i, bar().i, bar().i, bar().i, bar().i); }"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { int i; } f[2];\n" "struct Fred * bar() { return f; };\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { int i; } f[2];\n" "const struct Fred * bar() { return f; };\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { int i; } f[2];\n" "static const struct Fred * bar() { return f; };\n" "void foo() { printf(\"%d %u %lu %f %lf %p\", bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i, bar()[0].i); }"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer given in the argument list.\n" - "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number given in the argument list.\n" - "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lu in format string (no. 3) requires an unsigned long integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 4) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %lf in format string (no. 5) requires a floating point number but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %p in format string (no. 6) requires an address but the argument type is 'int'.\n", errout.str()); check("struct Fred { int32_t i; } f;\n" "struct Fred & bar() { };\n" @@ -1037,21 +1058,21 @@ private: "void f() {\n" " printf(\"%f\", foo()[0]);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires a floating point number but the argument type is 'int *'.\n", errout.str()); check("struct Base { int length() { } };\n" "struct Derived : public Base { };\n" "void foo(Derived * d) {\n" " printf(\"%f\", d.length());\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires a floating point number but the argument type is 'int'.\n", errout.str()); check("std::vector v;\n" "void foo() {\n" " printf(\"%d %u %f\", v[0], v[0], v[0]);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:3]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 3) requires a floating point number but the argument type is 'int'.\n", errout.str()); } @@ -1093,13 +1114,34 @@ private: " printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n" " printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n" " printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n" - "}"); - ASSERT_EQUALS("[test.cpp:8]: (warning) %Id in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:9]: (warning) %Iu in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:10]: (warning) %I32u in format string (no. 2) requires an unsigned integer given in the argument list.\n" - "[test.cpp:11]: (warning) %I32d in format string (no. 1) requires a signed integer given in the argument list.\n" - "[test.cpp:12]: (warning) %I64u in format string (no. 2) requires an unsigned long long integer given in the argument list.\n" - "[test.cpp:13]: (warning) %I64d in format string (no. 1) requires a signed long long integer given in the argument list.\n", errout.str()); + "}", false, false, Settings::Win32A); + ASSERT_EQUALS("[test.cpp:8]: (warning) %Id in format string (no. 1) requires a signed integer but the argument type is 'size_t {aka unsigned long}'.\n" + "[test.cpp:9]: (warning) %Iu in format string (no. 2) requires an unsigned integer but the argument type is 'ptrdiff_t {aka long}'.\n" + "[test.cpp:10]: (warning) %I32u in format string (no. 2) requires an unsigned integer but the argument type is '__int32 {aka int}'.\n" + "[test.cpp:11]: (warning) %I32d in format string (no. 1) requires a signed integer but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" + "[test.cpp:12]: (warning) %I64u in format string (no. 2) requires an unsigned long long integer but the argument type is '__int64 {aka long long}'.\n" + "[test.cpp:13]: (warning) %I64d in format string (no. 1) requires a signed long long integer but the argument type is 'unsigned __int64 {aka unsigned long long}'.\n", errout.str()); + + check("void foo() {\n" + " size_t s;\n" + " ptrdiff_t p;\n" + " __int32 i32;\n" + " unsigned __int32 u32;\n" + " __int64 i64;\n" + " unsigned __int64 u64;\n" + " printf(\"%Id %Iu %Ix\", s, s, s);\n" + " printf(\"%Id %Iu %Ix\", p, p, p);\n" + " printf(\"%I32d %I32u %I32x\", i32, i32, i32);\n" + " printf(\"%I32d %I32u %I32x\", u32, u32, u32);\n" + " printf(\"%I64d %I64u %I64x\", i64, i64, i64);\n" + " printf(\"%I64d %I64u %I64x\", u64, u64, u64);\n" + "}", false, false, Settings::Win64); + ASSERT_EQUALS("[test.cpp:8]: (warning) %Id in format string (no. 1) requires a signed integer but the argument type is 'size_t {aka unsigned long long}'.\n" + "[test.cpp:9]: (warning) %Iu in format string (no. 2) requires an unsigned integer but the argument type is 'ptrdiff_t {aka long long}'.\n" + "[test.cpp:10]: (warning) %I32u in format string (no. 2) requires an unsigned integer but the argument type is '__int32 {aka int}'.\n" + "[test.cpp:11]: (warning) %I32d in format string (no. 1) requires a signed integer but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" + "[test.cpp:12]: (warning) %I64u in format string (no. 2) requires an unsigned long long integer but the argument type is '__int64 {aka long long}'.\n" + "[test.cpp:13]: (warning) %I64d in format string (no. 1) requires a signed long long integer but the argument type is 'unsigned __int64 {aka unsigned long long}'.\n", errout.str()); check("void foo() {\n" " size_t s;\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 349648ea4..7161764f3 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8208,11 +8208,11 @@ private: "unsigned int sizeof_wchar_t ; sizeof_wchar_t = 4 ; " "unsigned int sizeof_pointer ; sizeof_pointer = 8 ; " "unsigned int sizeof_size_t ; sizeof_size_t = 8 ; " - "unsigned long long a ; " - "long long b ; " - "long long c ; " - "long long d ; " - "unsigned long long e ;"; + "unsigned long a ; " + "long b ; " + "long c ; " + "long d ; " + "unsigned long e ;"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Unix64)); }