From b457ceef0ed78b148c78577f071f6cf8fe67038e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 1 Jan 2016 17:33:59 +0100 Subject: [PATCH] Settings: Added defaultSign --- lib/settings.cpp | 31 +++++++++------ lib/settings.h | 2 + lib/symboldatabase.cpp | 76 ++++++++++++++++++++----------------- lib/symboldatabase.h | 2 +- lib/tokenize.cpp | 2 +- test/testcharvar.cpp | 1 + test/testio.cpp | 2 +- test/testsymboldatabase.cpp | 4 +- 8 files changed, 71 insertions(+), 49 deletions(-) diff --git a/lib/settings.cpp b/lib/settings.cpp index 30dc83f79..f2306ef4d 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -141,17 +141,18 @@ bool Settings::platform(PlatformType type) switch (type) { case Unspecified: platformType = type; - sizeof_bool = 1; - sizeof_short = 1; - sizeof_int = 1; - sizeof_long = 1; - sizeof_long_long = 1; - sizeof_float = 1; - sizeof_double = 1; - sizeof_long_double = 1; - sizeof_wchar_t = 1; - sizeof_size_t = 1; - sizeof_pointer = 1; + 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_wchar_t = sizeof(wchar_t); + sizeof_size_t = sizeof(std::size_t); + sizeof_pointer = sizeof(void *); + defaultSign = '\0'; return true; case Native: // same as system this code was compile on platformType = type; @@ -166,6 +167,10 @@ bool Settings::platform(PlatformType type) sizeof_wchar_t = sizeof(wchar_t); sizeof_size_t = sizeof(std::size_t); sizeof_pointer = sizeof(void *); + { + int x = 2; + defaultSign = (-10 / x == -5) ? 's' : 'u'; + } return true; case Win32W: case Win32A: @@ -181,6 +186,7 @@ bool Settings::platform(PlatformType type) sizeof_wchar_t = 2; sizeof_size_t = 4; sizeof_pointer = 4; + defaultSign = '\0'; return true; case Win64: platformType = type; @@ -195,6 +201,7 @@ bool Settings::platform(PlatformType type) sizeof_wchar_t = 2; sizeof_size_t = 8; sizeof_pointer = 8; + defaultSign = '\0'; return true; case Unix32: platformType = type; @@ -209,6 +216,7 @@ bool Settings::platform(PlatformType type) sizeof_wchar_t = 4; sizeof_size_t = 4; sizeof_pointer = 4; + defaultSign = '\0'; return true; case Unix64: platformType = type; @@ -223,6 +231,7 @@ bool Settings::platform(PlatformType type) sizeof_wchar_t = 4; sizeof_size_t = 8; sizeof_pointer = 8; + defaultSign = '\0'; return true; } diff --git a/lib/settings.h b/lib/settings.h index 4f6fc47e3..91924232f 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -253,6 +253,8 @@ public: unsigned int sizeof_size_t; unsigned int sizeof_pointer; + char defaultSign; // unsigned:'u', signed:'s', unknown:'\0' + enum PlatformType { Unspecified, // No platform specified Native, // whatever system this code was compiled on diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f2fb38a71..2e870b61f 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3654,19 +3654,19 @@ bool SymbolDatabase::isReservedName(const std::string& iName) const return c_keywords.find(iName) != c_keywords.cend(); } -static const Token * parsedecl(const Token *type, ValueType * const valuetype); -static void setValueType(Token *tok, const ValueType &valuetype); +static const Token * parsedecl(const Token *type, ValueType * const valuetype, ValueType::Sign defaultSignedness); +static void setValueType(Token *tok, const ValueType &valuetype, ValueType::Sign defaultSignedness); -static void setValueType(Token *tok, const Variable &var) +static void setValueType(Token *tok, const Variable &var, ValueType::Sign defaultSignedness) { ValueType valuetype; valuetype.pointer = var.dimensions().size(); valuetype.typeScope = var.typeScope(); - if (parsedecl(var.typeStartToken(), &valuetype)) - ::setValueType(tok, valuetype); + if (parsedecl(var.typeStartToken(), &valuetype, defaultSignedness)) + setValueType(tok, valuetype, defaultSignedness); } -static void setValueType(Token *tok, const ValueType &valuetype) +static void setValueType(Token *tok, const ValueType &valuetype, ValueType::Sign defaultSignedness) { tok->setValueType(new ValueType(valuetype)); Token *parent = const_cast(tok->astParent()); @@ -3676,7 +3676,7 @@ static void setValueType(Token *tok, const ValueType &valuetype) return; if (Token::Match(parent, "<<|>>")) { - setValueType(parent,valuetype); + setValueType(parent,valuetype, defaultSignedness); return; } @@ -3684,20 +3684,20 @@ static void setValueType(Token *tok, const ValueType &valuetype) ValueType vt(valuetype); vt.pointer -= 1U; vt.constness >>= 1; - setValueType(parent, vt); + setValueType(parent, vt, defaultSignedness); return; } if (parent->str() == "*" && !parent->astOperand2() && valuetype.pointer > 0U) { ValueType vt(valuetype); vt.pointer -= 1U; vt.constness >>= 1; - setValueType(parent, vt); + setValueType(parent, vt, defaultSignedness); return; } if (parent->str() == "&" && !parent->astOperand2()) { ValueType vt(valuetype); vt.pointer += 1U; - setValueType(parent, vt); + setValueType(parent, vt, defaultSignedness); return; } @@ -3711,7 +3711,7 @@ static void setValueType(Token *tok, const ValueType &valuetype) for (std::list::const_iterator it = typeScope->varlist.begin(); it != typeScope->varlist.end(); ++it) { const Variable &var = *it; if (var.nameToken()->str() == name) { - setValueType(parent, var); + setValueType(parent, var, defaultSignedness); return; } } @@ -3723,30 +3723,30 @@ static void setValueType(Token *tok, const ValueType &valuetype) const ValueType *vt2 = parent->astOperand2() ? parent->astOperand2()->valueType() : nullptr; if (parent->isArithmeticalOp() && vt2) { if (vt1->pointer != 0U && vt2->pointer == 0U) { - setValueType(parent, *vt1); + setValueType(parent, *vt1, defaultSignedness); return; } if (vt1->pointer == 0U && vt2->pointer != 0U) { - setValueType(parent, *vt2); + setValueType(parent, *vt2, defaultSignedness); return; } if (vt1->pointer != 0U) { // result is pointer diff - setValueType(parent, ValueType(ValueType::Sign::UNSIGNED, ValueType::Type::INT, 0U, 0U, "ptrdiff_t")); + setValueType(parent, ValueType(ValueType::Sign::UNSIGNED, ValueType::Type::INT, 0U, 0U, "ptrdiff_t"), defaultSignedness); return; } if (vt1->type == ValueType::Type::LONGDOUBLE || vt2->type == ValueType::Type::LONGDOUBLE) { - setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::LONGDOUBLE, 0U)); + setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::LONGDOUBLE, 0U), defaultSignedness); return; } if (vt1->type == ValueType::Type::DOUBLE || vt2->type == ValueType::Type::DOUBLE) { - setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::DOUBLE, 0U)); + setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::DOUBLE, 0U), defaultSignedness); return; } if (vt1->type == ValueType::Type::FLOAT || vt2->type == ValueType::Type::FLOAT) { - setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::FLOAT, 0U)); + setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::FLOAT, 0U), defaultSignedness); return; } } @@ -3781,17 +3781,17 @@ static void setValueType(Token *tok, const ValueType &valuetype) vt.originalTypeName.clear(); } - setValueType(parent, vt); + setValueType(parent, vt, defaultSignedness); return; } } -static const Token * parsedecl(const Token *type, ValueType * const valuetype) +static const Token * parsedecl(const Token *type, ValueType * const valuetype, ValueType::Sign defaultSignedness) { const unsigned int pointer0 = valuetype->pointer; while (Token::Match(type->previous(), "%name%")) type = type->previous(); - valuetype->sign = ValueType::Sign::UNKNOWN_SIGN; + valuetype->sign = defaultSignedness; valuetype->type = ValueType::Type::UNKNOWN_TYPE; while (Token::Match(type, "%name%|*|&") && !type->variable()) { if (type->isSigned()) @@ -3827,8 +3827,16 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype) return (type && valuetype->type != ValueType::Type::UNKNOWN_TYPE) ? type : nullptr; } -void SymbolDatabase::setValueTypeInTokenList(Token *tokens) +void SymbolDatabase::setValueTypeInTokenList(Token *tokens, char defaultSignedness) { + ValueType::Sign defsign; + if (defaultSignedness == 's' || defaultSignedness == 'S') + defsign = ValueType::SIGNED; + else if (defaultSignedness == 'u' || defaultSignedness == 'U') + defsign = ValueType::UNSIGNED; + else + defsign = ValueType::UNKNOWN_SIGN; + for (Token *tok = tokens; tok; tok = tok->next()) tok->setValueType(nullptr); @@ -3838,7 +3846,7 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens) ValueType::Type type = ValueType::Type::DOUBLE; if (tok->str()[tok->str().size() - 1U] == 'f') type = ValueType::Type::FLOAT; - ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, type, 0U)); + ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, type, 0U), defsign); } else if (MathLib::isInt(tok->str())) { ValueType::Sign sign = ValueType::Sign::SIGNED; ValueType::Type type = ValueType::Type::INT; @@ -3852,49 +3860,49 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens) else type = ValueType::Type::LONG; } - ::setValueType(tok, ValueType(sign, type, 0U)); + ::setValueType(tok, ValueType(sign, type, 0U), defsign); } } else if (tok->isComparisonOp()) - ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::BOOL, 0U)); + ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::BOOL, 0U), defsign); else if (tok->tokType() == Token::eChar) - ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 0U)); + ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 0U), defsign); else if (tok->tokType() == Token::eString) { ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 1U, 1U); if (tok->isLong()) { valuetype.originalTypeName = "wchar_t"; valuetype.type = ValueType::Type::SHORT; } - ::setValueType(tok, valuetype); + ::setValueType(tok, valuetype, defsign); } else if (tok->str() == "(") { // cast if (!tok->astOperand2() && Token::Match(tok, "( %name%")) { ValueType valuetype; - if (Token::simpleMatch(parsedecl(tok->next(), &valuetype), ")")) - ::setValueType(tok, valuetype); + if (Token::simpleMatch(parsedecl(tok->next(), &valuetype, defsign), ")")) + ::setValueType(tok, valuetype, defsign); } // C++ cast if (tok->astOperand2() && Token::Match(tok->astOperand1(), "static_cast|const_cast|dynamic_cast|reinterpret_cast < %name%") && tok->astOperand1()->linkAt(1)) { ValueType valuetype; - if (Token::simpleMatch(parsedecl(tok->astOperand1()->tokAt(2), &valuetype), ">")) - ::setValueType(tok, valuetype); + if (Token::simpleMatch(parsedecl(tok->astOperand1()->tokAt(2), &valuetype, defsign), ">")) + ::setValueType(tok, valuetype, defsign); } // function else if (tok->previous() && tok->previous()->function() && tok->previous()->function()->retDef) { ValueType valuetype; - if (Token::simpleMatch(parsedecl(tok->previous()->function()->retDef, &valuetype), "(")) - ::setValueType(tok, valuetype); + if (Token::simpleMatch(parsedecl(tok->previous()->function()->retDef, &valuetype, defsign), "(")) + ::setValueType(tok, valuetype, defsign); } else if (Token::simpleMatch(tok->previous(), "sizeof (")) { // TODO: use specified size_t type ValueType valuetype(ValueType::Sign::UNSIGNED, ValueType::Type::LONG, 0U); valuetype.originalTypeName = "size_t"; - setValueType(tok, valuetype); + setValueType(tok, valuetype, defsign); } } else if (tok->variable()) { - setValueType(tok, *tok->variable()); + setValueType(tok, *tok->variable(), defsign); } } } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 4e53d192b..f62d2469f 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1013,7 +1013,7 @@ public: void validate() const; /** Set valuetype in provided tokenlist */ - static void setValueTypeInTokenList(Token *tokens); + static void setValueTypeInTokenList(Token *tokens, char defaultSignedness); private: friend class Scope; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 5642303b6..718c37c14 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1746,7 +1746,7 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration, list.createAst(); list.validateAst(); - SymbolDatabase::setValueTypeInTokenList(list.front()); + SymbolDatabase::setValueTypeInTokenList(list.front(), _settings->defaultSign); ValueFlow::setValues(&list, _symbolDatabase, _errorLogger, _settings); } diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index 2b2605ab8..fa9d941b5 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -30,6 +30,7 @@ private: Settings settings; void run() { + settings.platform(Settings::Unspecified); settings.addEnabled("warning"); TEST_CASE(array_index_1); diff --git a/test/testio.cpp b/test/testio.cpp index 16e384e7f..30ead84b3 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -62,7 +62,7 @@ private: TEST_CASE(testAstType); // #7014 } - void check(const char code[], bool inconclusive = false, bool portability = false, Settings::PlatformType platform = Settings::Native) { + void check(const char code[], bool inconclusive = false, bool portability = false, Settings::PlatformType platform = Settings::Unspecified) { // Clear the error buffer.. errout.str(""); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index a16565d85..d12998d34 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3000,7 +3000,9 @@ private: } std::string typeOf(const char code[], const char str[]) { - Tokenizer tokenizer(&settings, this); + Settings s; + s.platform(Settings::Unspecified); + Tokenizer tokenizer(&s, this); std::istringstream istr(code); tokenizer.tokenize(istr, "test.cpp"); const Token * const tok = Token::findsimplematch(tokenizer.tokens(),str);