fix #2888 (Allow defining sizes of base types)

This commit is contained in:
Robert Reif 2011-09-17 19:40:52 -04:00
parent 9e8a3f33f8
commit b5d22fda0d
5 changed files with 300 additions and 23 deletions

View File

@ -591,6 +591,29 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
_settings->checkConfiguration = true; _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 // Print help
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) 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" " more comments, like: // cppcheck-suppress warningId\n"
" on the lines before the warning to suppress.\n" " on the lines before the warning to suppress.\n"
" -j <jobs> Start [jobs] threads to do the checking simultaneously.\n" " -j <jobs> Start [jobs] threads to do the checking simultaneously.\n"
" --platform=<type> 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" " -q, --quiet Only print error messages.\n"
" --report-progress Report progress messages while checking a file.\n" " --report-progress Report progress messages while checking a file.\n"
#ifdef HAVE_RULES #ifdef HAVE_RULES

View File

@ -50,6 +50,18 @@ Settings::Settings()
ifcfg = false; ifcfg = false;
checkConfiguration = false; checkConfiguration = false;
posix = 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) std::string Settings::addEnabled(const std::string &str)
@ -126,3 +138,71 @@ std::string Settings::append() const
{ {
return _append; 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;
}

View File

@ -190,6 +190,33 @@ public:
/** Code is posix - it is not compatible with non-posix environments */ /** Code is posix - it is not compatible with non-posix environments */
bool posix; 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);
}; };
/// @} /// @}

View File

@ -225,9 +225,9 @@ unsigned int Tokenizer::sizeOfType(const Token *type) const
else if (type->isLong()) else if (type->isLong())
{ {
if (type->str() == "double") if (type->str() == "double")
return sizeof(long double); return _settings->sizeof_long_double;
else if (type->str() == "long") else if (type->str() == "long")
return sizeof(long long); return _settings->sizeof_long_long;
} }
return it->second; return it->second;
@ -2146,6 +2146,18 @@ bool Tokenizer::tokenize(std::istream &code,
// make sure settings specified // make sure settings specified
assert(_settings); 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; _configuration = configuration;
// The "_files" vector remembers what files have been tokenized.. // 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 // TODO: this is a bit hardcoded. make a bit more generic
if (Token::Match(tok2, "%var% < sizeof ( %type% ) >") && tok2->tokAt(4)->isStandardType()) 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(); Token * const tok3 = tok2->next();
const unsigned int sz = sizeOfType(tok3->tokAt(3)); const unsigned int sz = sizeOfType(tok3->tokAt(3));
Token::eraseTokens(tok3, tok3->tokAt(5)); Token::eraseTokens(tok3, tok3->tokAt(5));
@ -4230,17 +4233,6 @@ bool Tokenizer::createLinks()
void Tokenizer::simplifySizeof() 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()) for (Token *tok = _tokens; tok; tok = tok->next())
{ {
if (Token::Match(tok, "class|struct %var%")) if (Token::Match(tok, "class|struct %var%"))

View File

@ -358,6 +358,11 @@ private:
//remove redundant code after the 'return ;' statement //remove redundant code after the 'return ;' statement
TEST_CASE(removeRedundantCodeAfterReturn); 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(""); errout.str("");
Settings settings; Settings settings;
settings.debugwarnings = true; settings.debugwarnings = true;
settings.platform(platform);
// tokenize.. // tokenize..
Tokenizer tokenizer(&settings, this); 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)); 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) REGISTER_TEST(TestTokenizer)