Settings: Added defaultSign
This commit is contained in:
parent
f5715c1496
commit
b457ceef0e
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Token *>(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<Variable>::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ private:
|
|||
Settings settings;
|
||||
|
||||
void run() {
|
||||
settings.platform(Settings::Unspecified);
|
||||
settings.addEnabled("warning");
|
||||
|
||||
TEST_CASE(array_index_1);
|
||||
|
|
|
@ -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("");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue