From b5d22fda0dcaa2d76c74e9792701a5fe52d480c6 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 17 Sep 2011 19:40:52 -0400 Subject: [PATCH] fix #2888 (Allow defining sizes of base types) --- cli/cmdlineparser.cpp | 32 +++++++++ lib/settings.cpp | 80 +++++++++++++++++++++++ lib/settings.h | 27 ++++++++ lib/tokenize.cpp | 36 ++++------ test/testtokenize.cpp | 148 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 300 insertions(+), 23 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 0885e3f1a..8ec4d2f0b 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -591,6 +591,29 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) _settings->checkConfiguration = true; } + // Specify platform + else if (strncmp(argv[i], "--platform=", 11) == 0) + { + std::string platform(11+argv[i]); + + if (platform == "win32") + _settings->platform(Settings::Win32); + else if (platform == "win64") + _settings->platform(Settings::Win64); + else if (platform == "unix32") + _settings->platform(Settings::Unix32); + else if (platform == "unix64") + _settings->platform(Settings::Unix64); + else + { + std::string message("cppcheck: error: unrecognized platform\""); + message += argv[i]; + message += "\""; + PrintMessage(message); + return false; + } + } + // Print help else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { @@ -710,6 +733,15 @@ void CmdLineParser::PrintHelp() " more comments, like: // cppcheck-suppress warningId\n" " on the lines before the warning to suppress.\n" " -j Start [jobs] threads to do the checking simultaneously.\n" + " --platform= Specifies platform specific types and sizes. The available platforms are:\n" + " * unix32\n" + " 32 bit unix variant\n" + " * unix64\n" + " 64 bit unix variant\n" + " * win32\n" + " 32 bit Windows\n" + " * win64\n" + " 64 bit Windows\n" " -q, --quiet Only print error messages.\n" " --report-progress Report progress messages while checking a file.\n" #ifdef HAVE_RULES diff --git a/lib/settings.cpp b/lib/settings.cpp index 03228d45d..a5ba4277a 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -50,6 +50,18 @@ Settings::Settings() ifcfg = false; checkConfiguration = false; posix = false; + + // This assumes the code you are checking is for the same architecture this is compiled on. + sizeof_bool = sizeof(bool); + sizeof_short = sizeof(short); + sizeof_int = sizeof(int); + sizeof_long = sizeof(long); + sizeof_long_long = sizeof(long long); + sizeof_float = sizeof(float); + sizeof_double = sizeof(double); + sizeof_long_double = sizeof(long double); + sizeof_size_t = sizeof(size_t); + sizeof_pointer = sizeof(void *); } std::string Settings::addEnabled(const std::string &str) @@ -126,3 +138,71 @@ std::string Settings::append() const { return _append; } + +bool Settings::platform(PlatformType type) +{ + switch (type) + { + case Host: // same as system this code was compile on + return true; + case Win32: + sizeof_bool = 1; // 4 in Visual C++ 4.2 + sizeof_short = 2; + sizeof_int = 4; + sizeof_long = 4; + sizeof_long_long = 8; + sizeof_float = 4; + sizeof_double = 8; + sizeof_long_double = 8; + sizeof_size_t = 4; + sizeof_pointer = 4; + return true; + case Win64: + sizeof_bool = 1; + sizeof_short = 2; + sizeof_int = 4; + sizeof_long = 4; + sizeof_long_long = 8; + sizeof_float = 4; + sizeof_double = 8; + sizeof_long_double = 8; + sizeof_size_t = 8; + sizeof_pointer = 8; + return true; + case Unix32: + sizeof_bool = 1; + sizeof_short = 2; + sizeof_int = 4; + sizeof_long = 4; + sizeof_long_long = 8; + sizeof_float = 4; + sizeof_double = 8; + sizeof_long_double = 12; + sizeof_size_t = 4; + sizeof_pointer = 4; + return true; + case Unix64: + sizeof_bool = 1; + sizeof_short = 2; + sizeof_int = 4; + sizeof_long = 8; + sizeof_long_long = 8; + sizeof_float = 4; + sizeof_double = 8; + sizeof_long_double = 12; + sizeof_size_t = 8; + sizeof_pointer = 8; + return true; + } + + // unsupported platform + return false; +} + +bool Settings::platformFile(const std::string &filename) +{ + (void)filename; + /** @todo TBD */ + + return false; +} diff --git a/lib/settings.h b/lib/settings.h index fb8da5de0..3e6e6f792 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -190,6 +190,33 @@ public: /** Code is posix - it is not compatible with non-posix environments */ bool posix; + + /** size of standard types */ + unsigned int sizeof_bool; + unsigned int sizeof_short; + unsigned int sizeof_int; + unsigned int sizeof_long; + unsigned int sizeof_long_long; + unsigned int sizeof_float; + unsigned int sizeof_double; + unsigned int sizeof_long_double; + unsigned int sizeof_size_t; + unsigned int sizeof_pointer; + + enum PlatformType + { + Host, // whatever system this code was compiled on + Win32, + Win64, + Unix32, + Unix64 + }; + + /** set the platform type for predefined platforms */ + bool platform(PlatformType type); + + /** set the platform type for user specified platforms */ + bool platformFile(const std::string &filename); }; /// @} diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 58d030438..0a4b63252 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -225,9 +225,9 @@ unsigned int Tokenizer::sizeOfType(const Token *type) const else if (type->isLong()) { if (type->str() == "double") - return sizeof(long double); + return _settings->sizeof_long_double; else if (type->str() == "long") - return sizeof(long long); + return _settings->sizeof_long_long; } return it->second; @@ -2146,6 +2146,18 @@ bool Tokenizer::tokenize(std::istream &code, // make sure settings specified assert(_settings); + // Fill the map _typeSize.. + _typeSize.clear(); + _typeSize["char"] = 1; + _typeSize["bool"] = _settings->sizeof_bool; + _typeSize["short"] = _settings->sizeof_short; + _typeSize["int"] = _settings->sizeof_int; + _typeSize["long"] = _settings->sizeof_long; + _typeSize["float"] = _settings->sizeof_float; + _typeSize["double"] = _settings->sizeof_double; + _typeSize["size_t"] = _settings->sizeof_size_t; + _typeSize["*"] = _settings->sizeof_pointer; + _configuration = configuration; // The "_files" vector remembers what files have been tokenized.. @@ -3272,15 +3284,6 @@ void Tokenizer::simplifyTemplatesInstantiate(const Token *tok, // TODO: this is a bit hardcoded. make a bit more generic if (Token::Match(tok2, "%var% < sizeof ( %type% ) >") && tok2->tokAt(4)->isStandardType()) { - // make sure standard types have a known size.. - _typeSize["char"] = sizeof(char); - _typeSize["short"] = sizeof(short); - _typeSize["int"] = sizeof(int); - _typeSize["long"] = sizeof(long); - _typeSize["float"] = sizeof(float); - _typeSize["double"] = sizeof(double); - _typeSize["size_t"] = sizeof(size_t); - Token * const tok3 = tok2->next(); const unsigned int sz = sizeOfType(tok3->tokAt(3)); Token::eraseTokens(tok3, tok3->tokAt(5)); @@ -4230,17 +4233,6 @@ bool Tokenizer::createLinks() void Tokenizer::simplifySizeof() { - // Fill the map _typeSize.. - _typeSize.clear(); - _typeSize["char"] = sizeof(char); - _typeSize["short"] = sizeof(short); - _typeSize["int"] = sizeof(int); - _typeSize["long"] = sizeof(long); - _typeSize["float"] = sizeof(float); - _typeSize["double"] = sizeof(double); - _typeSize["size_t"] = sizeof(size_t); - _typeSize["*"] = sizeof(void *); - for (Token *tok = _tokens; tok; tok = tok->next()) { if (Token::Match(tok, "class|struct %var%")) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 2d2425549..2699f80e5 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -358,6 +358,11 @@ private: //remove redundant code after the 'return ;' statement TEST_CASE(removeRedundantCodeAfterReturn); + + TEST_CASE(platformWin32); + TEST_CASE(platformWin64); + TEST_CASE(platformUnix32); + TEST_CASE(platformUnix64); } @@ -373,12 +378,13 @@ private: } - std::string tokenizeAndStringify(const char code[], bool simplify = false) + std::string tokenizeAndStringify(const char code[], bool simplify = false, Settings::PlatformType platform = Settings::Host) { errout.str(""); Settings settings; settings.debugwarnings = true; + settings.platform(platform); // tokenize.. Tokenizer tokenizer(&settings, this); @@ -5932,6 +5938,146 @@ private: ASSERT_EQUALS("int f ( ) { switch ( x ) { case 1 : return 1 ; case 2 : switch ( y ) { case 1 : return 0 ; case 2 : return 7 ; } return 2 ; } return 3 ; }",simplifyKnownVariables(code)); } } + + void platformWin32() + { + const char code[] = "unsigned int sizeof_short = sizeof(short);" + "unsigned int sizeof_unsigned_short = sizeof(unsigned short);" + "unsigned int sizeof_int = sizeof(int);" + "unsigned int sizeof_unsigned_int = sizeof(unsigned int);" + "unsigned int sizeof_long = sizeof(long);" + "unsigned int sizeof_unsigned_long = sizeof(unsigned long);" + "unsigned int sizeof_long_long = sizeof(long long);" + "unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);" + "unsigned int sizeof_float = sizeof(float);" + "unsigned int sizeof_double = sizeof(double);" + "unsigned int sizeof_long_double = sizeof(long double);" + "unsigned int sizeof_bool = sizeof(bool);" + "unsigned int sizeof_pointer = sizeof(void *);" + "unsigned int sizeof_size_t = sizeof(size_t);"; + + const char expected[] = "int sizeof_short ; sizeof_short = 2 ; " + "int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; " + "int sizeof_int ; sizeof_int = 4 ; " + "int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; " + "int sizeof_long ; sizeof_long = 4 ; " + "int sizeof_unsigned_long ; sizeof_unsigned_long = 4 ; " + "int sizeof_long_long ; sizeof_long_long = 8 ; " + "int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; " + "int sizeof_float ; sizeof_float = 4 ; " + "int sizeof_double ; sizeof_double = 8 ; " + "int sizeof_long_double ; sizeof_long_double = 8 ; " + "int sizeof_bool ; sizeof_bool = 1 ; " + "int sizeof_pointer ; sizeof_pointer = 4 ; " + "int sizeof_size_t ; sizeof_size_t = 4 ;"; + + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Settings::Win32)); + } + + void platformWin64() + { + const char code[] = "unsigned int sizeof_short = sizeof(short);" + "unsigned int sizeof_unsigned_short = sizeof(unsigned short);" + "unsigned int sizeof_int = sizeof(int);" + "unsigned int sizeof_unsigned_int = sizeof(unsigned int);" + "unsigned int sizeof_long = sizeof(long);" + "unsigned int sizeof_unsigned_long = sizeof(unsigned long);" + "unsigned int sizeof_long_long = sizeof(long long);" + "unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);" + "unsigned int sizeof_float = sizeof(float);" + "unsigned int sizeof_double = sizeof(double);" + "unsigned int sizeof_long_double = sizeof(long double);" + "unsigned int sizeof_bool = sizeof(bool);" + "unsigned int sizeof_pointer = sizeof(void *);" + "unsigned int sizeof_size_t = sizeof(size_t);"; + + const char expected[] = "int sizeof_short ; sizeof_short = 2 ; " + "int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; " + "int sizeof_int ; sizeof_int = 4 ; " + "int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; " + "int sizeof_long ; sizeof_long = 4 ; " + "int sizeof_unsigned_long ; sizeof_unsigned_long = 4 ; " + "int sizeof_long_long ; sizeof_long_long = 8 ; " + "int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; " + "int sizeof_float ; sizeof_float = 4 ; " + "int sizeof_double ; sizeof_double = 8 ; " + "int sizeof_long_double ; sizeof_long_double = 8 ; " + "int sizeof_bool ; sizeof_bool = 1 ; " + "int sizeof_pointer ; sizeof_pointer = 8 ; " + "int sizeof_size_t ; sizeof_size_t = 8 ;"; + + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Settings::Win64)); + } + + void platformUnix32() + { + const char code[] = "unsigned int sizeof_short = sizeof(short);" + "unsigned int sizeof_unsigned_short = sizeof(unsigned short);" + "unsigned int sizeof_int = sizeof(int);" + "unsigned int sizeof_unsigned_int = sizeof(unsigned int);" + "unsigned int sizeof_long = sizeof(long);" + "unsigned int sizeof_unsigned_long = sizeof(unsigned long);" + "unsigned int sizeof_long_long = sizeof(long long);" + "unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);" + "unsigned int sizeof_float = sizeof(float);" + "unsigned int sizeof_double = sizeof(double);" + "unsigned int sizeof_long_double = sizeof(long double);" + "unsigned int sizeof_bool = sizeof(bool);" + "unsigned int sizeof_pointer = sizeof(void *);" + "unsigned int sizeof_size_t = sizeof(size_t);"; + + const char expected[] = "int sizeof_short ; sizeof_short = 2 ; " + "int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; " + "int sizeof_int ; sizeof_int = 4 ; " + "int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; " + "int sizeof_long ; sizeof_long = 4 ; " + "int sizeof_unsigned_long ; sizeof_unsigned_long = 4 ; " + "int sizeof_long_long ; sizeof_long_long = 8 ; " + "int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; " + "int sizeof_float ; sizeof_float = 4 ; " + "int sizeof_double ; sizeof_double = 8 ; " + "int sizeof_long_double ; sizeof_long_double = 12 ; " + "int sizeof_bool ; sizeof_bool = 1 ; " + "int sizeof_pointer ; sizeof_pointer = 4 ; " + "int sizeof_size_t ; sizeof_size_t = 4 ;"; + + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Settings::Unix32)); + } + + void platformUnix64() + { + const char code[] = "unsigned int sizeof_short = sizeof(short);" + "unsigned int sizeof_unsigned_short = sizeof(unsigned short);" + "unsigned int sizeof_int = sizeof(int);" + "unsigned int sizeof_unsigned_int = sizeof(unsigned int);" + "unsigned int sizeof_long = sizeof(long);" + "unsigned int sizeof_unsigned_long = sizeof(unsigned long);" + "unsigned int sizeof_long_long = sizeof(long long);" + "unsigned int sizeof_unsigned_long_long = sizeof(unsigned long long);" + "unsigned int sizeof_float = sizeof(float);" + "unsigned int sizeof_double = sizeof(double);" + "unsigned int sizeof_long_double = sizeof(long double);" + "unsigned int sizeof_bool = sizeof(bool);" + "unsigned int sizeof_pointer = sizeof(void *);" + "unsigned int sizeof_size_t = sizeof(size_t);"; + + const char expected[] = "int sizeof_short ; sizeof_short = 2 ; " + "int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; " + "int sizeof_int ; sizeof_int = 4 ; " + "int sizeof_unsigned_int ; sizeof_unsigned_int = 4 ; " + "int sizeof_long ; sizeof_long = 8 ; " + "int sizeof_unsigned_long ; sizeof_unsigned_long = 8 ; " + "int sizeof_long_long ; sizeof_long_long = 8 ; " + "int sizeof_unsigned_long_long ; sizeof_unsigned_long_long = 8 ; " + "int sizeof_float ; sizeof_float = 4 ; " + "int sizeof_double ; sizeof_double = 8 ; " + "int sizeof_long_double ; sizeof_long_double = 12 ; " + "int sizeof_bool ; sizeof_bool = 1 ; " + "int sizeof_pointer ; sizeof_pointer = 8 ; " + "int sizeof_size_t ; sizeof_size_t = 8 ;"; + + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Settings::Unix64)); + } }; REGISTER_TEST(TestTokenizer)