Set wchar_t type (#1807)

This is necessary for valueflow to know the size, for example when
calculating sizeof(wchar_t).
This commit is contained in:
Rikard Falkeborn 2019-05-01 16:34:28 +02:00 committed by Daniel Marjamäki
parent 953895278b
commit 1cc5f3abe7
8 changed files with 35 additions and 5 deletions

View File

@ -1337,6 +1337,8 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings,
tempToken->str("char"); tempToken->str("char");
else if (valuetype->type == ValueType::SHORT) else if (valuetype->type == ValueType::SHORT)
tempToken->str("short"); tempToken->str("short");
else if (valuetype->type == ValueType::WCHAR_T)
tempToken->str("wchar_t");
else if (valuetype->type == ValueType::INT) else if (valuetype->type == ValueType::INT)
tempToken->str("int"); tempToken->str("int");
else if (valuetype->type == ValueType::LONG) else if (valuetype->type == ValueType::LONG)

View File

@ -78,6 +78,7 @@ void CheckType::checkTooBigBitwiseShift()
int lhsbits; int lhsbits;
if ((lhstype->type == ValueType::Type::CHAR) || if ((lhstype->type == ValueType::Type::CHAR) ||
(lhstype->type == ValueType::Type::SHORT) || (lhstype->type == ValueType::Type::SHORT) ||
(lhstype->type == ValueType::Type::WCHAR_T) ||
(lhstype->type == ValueType::Type::BOOL) || (lhstype->type == ValueType::Type::BOOL) ||
(lhstype->type == ValueType::Type::INT)) (lhstype->type == ValueType::Type::INT))
lhsbits = mSettings->int_bit; lhsbits = mSettings->int_bit;

View File

@ -4006,6 +4006,7 @@ static bool valueTypeMatch(const ValueType * valuetype, const Token * type)
return ((((type->str() == "bool" && valuetype->type == ValueType::BOOL) || return ((((type->str() == "bool" && valuetype->type == ValueType::BOOL) ||
(type->str() == "char" && valuetype->type == ValueType::CHAR) || (type->str() == "char" && valuetype->type == ValueType::CHAR) ||
(type->str() == "short" && valuetype->type == ValueType::SHORT) || (type->str() == "short" && valuetype->type == ValueType::SHORT) ||
(type->str() == "wchar_t" && valuetype->type == ValueType::WCHAR_T) ||
(type->str() == "int" && valuetype->type == ValueType::INT) || (type->str() == "int" && valuetype->type == ValueType::INT) ||
((type->str() == "long" && type->isLong()) && valuetype->type == ValueType::LONGLONG) || ((type->str() == "long" && type->isLong()) && valuetype->type == ValueType::LONGLONG) ||
(type->str() == "long" && valuetype->type == ValueType::LONG) || (type->str() == "long" && valuetype->type == ValueType::LONG) ||
@ -5352,7 +5353,7 @@ void SymbolDatabase::setValueTypeInTokenList()
ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 1U, 1U); ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 1U, 1U);
if (tok->isLong()) { if (tok->isLong()) {
valuetype.originalTypeName = "wchar_t"; valuetype.originalTypeName = "wchar_t";
valuetype.type = ValueType::Type::SHORT; valuetype.type = ValueType::Type::WCHAR_T;
} }
setValueType(tok, valuetype); setValueType(tok, valuetype);
} else if (tok->str() == "(") { } else if (tok->str() == "(") {
@ -5530,6 +5531,8 @@ ValueType::Type ValueType::typeFromString(const std::string &typestr, bool longT
return ValueType::Type::CHAR; return ValueType::Type::CHAR;
if (typestr == "short") if (typestr == "short")
return ValueType::Type::SHORT; return ValueType::Type::SHORT;
if (typestr == "wchar_t")
return ValueType::Type::WCHAR_T;
if (typestr == "int") if (typestr == "int")
return ValueType::Type::INT; return ValueType::Type::INT;
if (typestr == "long") if (typestr == "long")
@ -5567,6 +5570,8 @@ bool ValueType::fromLibraryType(const std::string &typestr, const Settings *sett
type = ValueType::Type::CHAR; type = ValueType::Type::CHAR;
else if (platformType->mType == "short") else if (platformType->mType == "short")
type = ValueType::Type::SHORT; type = ValueType::Type::SHORT;
else if (platformType->mType == "wchar_t")
type = ValueType::Type::WCHAR_T;
else if (platformType->mType == "int") else if (platformType->mType == "int")
type = platformType->_long ? ValueType::Type::LONG : ValueType::Type::INT; type = platformType->_long ? ValueType::Type::LONG : ValueType::Type::INT;
else if (platformType->mType == "long") else if (platformType->mType == "long")
@ -5629,6 +5634,9 @@ std::string ValueType::dump() const
case SHORT: case SHORT:
ret << "valueType-type=\"short\""; ret << "valueType-type=\"short\"";
break; break;
case WCHAR_T:
ret << "valueType-type=\"wchar_t\"";
break;
case INT: case INT:
ret << "valueType-type=\"int\""; ret << "valueType-type=\"int\"";
break; break;
@ -5690,6 +5698,8 @@ MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform) const
return 1; return 1;
case ValueType::Type::SHORT: case ValueType::Type::SHORT:
return platform.sizeof_short; return platform.sizeof_short;
case ValueType::Type::WCHAR_T:
return platform.sizeof_wchar_t;
case ValueType::Type::INT: case ValueType::Type::INT:
return platform.sizeof_int; return platform.sizeof_int;
case ValueType::Type::LONG: case ValueType::Type::LONG:
@ -5726,6 +5736,8 @@ std::string ValueType::str() const
ret += " char"; ret += " char";
else if (type == SHORT) else if (type == SHORT)
ret += " short"; ret += " short";
else if (type == WCHAR_T)
ret += " wchar_t";
else if (type == INT) else if (type == INT)
ret += " int"; ret += " int";
else if (type == LONG) else if (type == LONG)

View File

@ -1099,7 +1099,7 @@ private:
class CPPCHECKLIB ValueType { class CPPCHECKLIB ValueType {
public: public:
enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign; enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign;
enum Type { UNKNOWN_TYPE, NONSTD, RECORD, CONTAINER, ITERATOR, VOID, BOOL, CHAR, SHORT, INT, LONG, LONGLONG, UNKNOWN_INT, FLOAT, DOUBLE, LONGDOUBLE } type; enum Type { UNKNOWN_TYPE, NONSTD, RECORD, CONTAINER, ITERATOR, VOID, BOOL, CHAR, SHORT, WCHAR_T, INT, LONG, LONGLONG, UNKNOWN_INT, FLOAT, DOUBLE, LONGDOUBLE } type;
unsigned int bits; ///< bitfield bitcount unsigned int bits; ///< bitfield bitcount
unsigned int pointer; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc unsigned int pointer; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
unsigned int constness; ///< bit 0=data, bit 1=*, bit 2=** unsigned int constness; ///< bit 0=data, bit 1=*, bit 2=**

View File

@ -836,6 +836,8 @@ static size_t getSizeOf(const ValueType &vt, const Settings *settings)
return 1; return 1;
else if (vt.type == ValueType::Type::SHORT) else if (vt.type == ValueType::Type::SHORT)
return settings->sizeof_short; return settings->sizeof_short;
else if (vt.type == ValueType::Type::WCHAR_T)
return settings->sizeof_wchar_t;
else if (vt.type == ValueType::Type::INT) else if (vt.type == ValueType::Type::INT)
return settings->sizeof_int; return settings->sizeof_int;
else if (vt.type == ValueType::Type::LONG) else if (vt.type == ValueType::Type::LONG)
@ -1409,6 +1411,7 @@ static void valueFlowRightShift(TokenList *tokenList, const Settings* settings)
int lhsbits; int lhsbits;
if ((tok->astOperand1()->valueType()->type == ValueType::Type::CHAR) || if ((tok->astOperand1()->valueType()->type == ValueType::Type::CHAR) ||
(tok->astOperand1()->valueType()->type == ValueType::Type::SHORT) || (tok->astOperand1()->valueType()->type == ValueType::Type::SHORT) ||
(tok->astOperand1()->valueType()->type == ValueType::Type::WCHAR_T) ||
(tok->astOperand1()->valueType()->type == ValueType::Type::BOOL) || (tok->astOperand1()->valueType()->type == ValueType::Type::BOOL) ||
(tok->astOperand1()->valueType()->type == ValueType::Type::INT)) (tok->astOperand1()->valueType()->type == ValueType::Type::INT))
lhsbits = settings->int_bit; lhsbits = settings->int_bit;

View File

@ -5960,7 +5960,7 @@ private:
ASSERT_EQUALS("const char *", typeOf("\"hello\" + 1;", "+")); ASSERT_EQUALS("const char *", typeOf("\"hello\" + 1;", "+"));
ASSERT_EQUALS("const char", typeOf("\"hello\"[1];", "[")); ASSERT_EQUALS("const char", typeOf("\"hello\"[1];", "["));
ASSERT_EQUALS("const char", typeOf(";*\"hello\";", "*")); ASSERT_EQUALS("const char", typeOf(";*\"hello\";", "*"));
ASSERT_EQUALS("const short *", typeOf("L\"hello\" + 1;", "+")); ASSERT_EQUALS("const wchar_t *", typeOf("L\"hello\" + 1;", "+"));
// Variable calculations // Variable calculations
ASSERT_EQUALS("void *", typeOf("void *p; a = p + 1;", "+")); ASSERT_EQUALS("void *", typeOf("void *p; a = p + 1;", "+"));
@ -6107,6 +6107,17 @@ private:
ASSERT_EQUALS(true, vt.fromLibraryType("s32", &settingsUnix32)); ASSERT_EQUALS(true, vt.fromLibraryType("s32", &settingsUnix32));
ASSERT_EQUALS(ValueType::Type::INT, vt.type); ASSERT_EQUALS(ValueType::Type::INT, vt.type);
} }
{
// PlatformType - wchar_t
Settings settingsWin64;
settingsWin64.platformType = Settings::Win64;
Library::PlatformType lpctstr;
lpctstr.mType = "wchar_t";
settingsWin64.library.mPlatforms[settingsWin64.platformString()].mPlatformTypes["LPCTSTR"] = lpctstr;
ValueType vt;
ASSERT_EQUALS(true, vt.fromLibraryType("LPCTSTR", &settingsWin64));
ASSERT_EQUALS(ValueType::Type::WCHAR_T, vt.type);
}
{ {
// Container // Container
Settings sC; Settings sC;

View File

@ -81,8 +81,8 @@ private:
// signed types getting promoted to int sizeof(int) = 4 bytes // signed types getting promoted to int sizeof(int) = 4 bytes
// and signed types having already a size of 4 bytes // and signed types having already a size of 4 bytes
{ {
const std::string type[7] = {"signed char", "signed short", /*[signed]*/"short", /*[signed]*/"int", "signed int", /*[signed]*/"long", "signed long"}; const std::string type[8] = {"signed char", "signed short", /*[signed]*/"short", "wchar_t", /*[signed]*/"int", "signed int", /*[signed]*/"long", "signed long"};
for (short i = 0; i < 7U; ++i) { for (short i = 0; i < 8U; ++i) {
check((type[i] + " f(" + type[i] +" x) { return x << 33; }").c_str(),&settings); check((type[i] + " f(" + type[i] +" x) { return x << 33; }").c_str(),&settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 33 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 33 bits is undefined behaviour\n", errout.str());
check((type[i] + " f(int x) { return (x = (" + type[i] + ")x << 32); }").c_str(),&settings); check((type[i] + " f(int x) { return (x = (" + type[i] + ")x << 32); }").c_str(),&settings);

View File

@ -778,6 +778,7 @@ private:
CHECK("short", settings.sizeof_short); CHECK("short", settings.sizeof_short);
CHECK("int", settings.sizeof_int); CHECK("int", settings.sizeof_int);
CHECK("long", settings.sizeof_long); CHECK("long", settings.sizeof_long);
CHECK("wchar_t", settings.sizeof_wchar_t);
#undef CHECK #undef CHECK
// array size // array size