From 1cc5f3abe73e09d888f0d3f6dacddf70d212abf9 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Wed, 1 May 2019 16:34:28 +0200 Subject: [PATCH] Set wchar_t type (#1807) This is necessary for valueflow to know the size, for example when calculating sizeof(wchar_t). --- lib/checkio.cpp | 2 ++ lib/checktype.cpp | 1 + lib/symboldatabase.cpp | 14 +++++++++++++- lib/symboldatabase.h | 2 +- lib/valueflow.cpp | 3 +++ test/testsymboldatabase.cpp | 13 ++++++++++++- test/testtype.cpp | 4 ++-- test/testvalueflow.cpp | 1 + 8 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 208a54a9e..f3eb73606 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -1337,6 +1337,8 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings, tempToken->str("char"); else if (valuetype->type == ValueType::SHORT) tempToken->str("short"); + else if (valuetype->type == ValueType::WCHAR_T) + tempToken->str("wchar_t"); else if (valuetype->type == ValueType::INT) tempToken->str("int"); else if (valuetype->type == ValueType::LONG) diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 057ea9ee2..929bb9eeb 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -78,6 +78,7 @@ void CheckType::checkTooBigBitwiseShift() int lhsbits; if ((lhstype->type == ValueType::Type::CHAR) || (lhstype->type == ValueType::Type::SHORT) || + (lhstype->type == ValueType::Type::WCHAR_T) || (lhstype->type == ValueType::Type::BOOL) || (lhstype->type == ValueType::Type::INT)) lhsbits = mSettings->int_bit; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f7127795d..6f69ac6c3 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4006,6 +4006,7 @@ static bool valueTypeMatch(const ValueType * valuetype, const Token * type) return ((((type->str() == "bool" && valuetype->type == ValueType::BOOL) || (type->str() == "char" && valuetype->type == ValueType::CHAR) || (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() == "long" && type->isLong()) && valuetype->type == ValueType::LONGLONG) || (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); if (tok->isLong()) { valuetype.originalTypeName = "wchar_t"; - valuetype.type = ValueType::Type::SHORT; + valuetype.type = ValueType::Type::WCHAR_T; } setValueType(tok, valuetype); } else if (tok->str() == "(") { @@ -5530,6 +5531,8 @@ ValueType::Type ValueType::typeFromString(const std::string &typestr, bool longT return ValueType::Type::CHAR; if (typestr == "short") return ValueType::Type::SHORT; + if (typestr == "wchar_t") + return ValueType::Type::WCHAR_T; if (typestr == "int") return ValueType::Type::INT; if (typestr == "long") @@ -5567,6 +5570,8 @@ bool ValueType::fromLibraryType(const std::string &typestr, const Settings *sett type = ValueType::Type::CHAR; else if (platformType->mType == "short") type = ValueType::Type::SHORT; + else if (platformType->mType == "wchar_t") + type = ValueType::Type::WCHAR_T; else if (platformType->mType == "int") type = platformType->_long ? ValueType::Type::LONG : ValueType::Type::INT; else if (platformType->mType == "long") @@ -5629,6 +5634,9 @@ std::string ValueType::dump() const case SHORT: ret << "valueType-type=\"short\""; break; + case WCHAR_T: + ret << "valueType-type=\"wchar_t\""; + break; case INT: ret << "valueType-type=\"int\""; break; @@ -5690,6 +5698,8 @@ MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform) const return 1; case ValueType::Type::SHORT: return platform.sizeof_short; + case ValueType::Type::WCHAR_T: + return platform.sizeof_wchar_t; case ValueType::Type::INT: return platform.sizeof_int; case ValueType::Type::LONG: @@ -5726,6 +5736,8 @@ std::string ValueType::str() const ret += " char"; else if (type == SHORT) ret += " short"; + else if (type == WCHAR_T) + ret += " wchar_t"; else if (type == INT) ret += " int"; else if (type == LONG) diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index faa78abfb..ea60721cc 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1099,7 +1099,7 @@ private: class CPPCHECKLIB ValueType { public: 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 pointer; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc unsigned int constness; ///< bit 0=data, bit 1=*, bit 2=** diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 48d307ff2..014a8c619 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -836,6 +836,8 @@ static size_t getSizeOf(const ValueType &vt, const Settings *settings) return 1; else if (vt.type == ValueType::Type::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) return settings->sizeof_int; else if (vt.type == ValueType::Type::LONG) @@ -1409,6 +1411,7 @@ static void valueFlowRightShift(TokenList *tokenList, const Settings* settings) int lhsbits; if ((tok->astOperand1()->valueType()->type == ValueType::Type::CHAR) || (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::INT)) lhsbits = settings->int_bit; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 378377060..4a8066fd0 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -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\";", "*")); - ASSERT_EQUALS("const short *", typeOf("L\"hello\" + 1;", "+")); + ASSERT_EQUALS("const wchar_t *", typeOf("L\"hello\" + 1;", "+")); // Variable calculations ASSERT_EQUALS("void *", typeOf("void *p; a = p + 1;", "+")); @@ -6107,6 +6107,17 @@ private: ASSERT_EQUALS(true, vt.fromLibraryType("s32", &settingsUnix32)); 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 Settings sC; diff --git a/test/testtype.cpp b/test/testtype.cpp index 66772526f..54681339a 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -81,8 +81,8 @@ private: // signed types getting promoted to int sizeof(int) = 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"}; - for (short i = 0; i < 7U; ++i) { + 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 < 8U; ++i) { 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()); check((type[i] + " f(int x) { return (x = (" + type[i] + ")x << 32); }").c_str(),&settings); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 0a3ce01c9..26820e14b 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -778,6 +778,7 @@ private: CHECK("short", settings.sizeof_short); CHECK("int", settings.sizeof_int); CHECK("long", settings.sizeof_long); + CHECK("wchar_t", settings.sizeof_wchar_t); #undef CHECK // array size