ValueFlow: Better handling of casts
This commit is contained in:
parent
b9c65f0540
commit
606bb78297
|
@ -284,6 +284,21 @@ static bool addValue(Token *tok, const ValueFlow::Value &value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign sign, unsigned int bit)
|
||||||
|
{
|
||||||
|
if (value.isFloatValue()) {
|
||||||
|
value.valueType = ValueFlow::Value::INT;
|
||||||
|
value.intvalue = value.floatValue;
|
||||||
|
}
|
||||||
|
if (bit < 64) {
|
||||||
|
value.intvalue &= (1ULL << bit) - 1ULL;
|
||||||
|
if (sign == ValueType::Sign::SIGNED && value.intvalue & (1ULL << (bit - 1ULL))) {
|
||||||
|
value.intvalue |= ~((1ULL << bit) - 1ULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/** set ValueFlow value and perform calculations if possible */
|
/** set ValueFlow value and perform calculations if possible */
|
||||||
static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Settings *settings)
|
static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Settings *settings)
|
||||||
{
|
{
|
||||||
|
@ -294,13 +309,23 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: Cast..
|
|
||||||
/*
|
|
||||||
if (parent->str() == "(" && tok == parent->link()->next()) {
|
if (parent->str() == "(" && tok == parent->link()->next()) {
|
||||||
setTokenValue(parent,value,settings);
|
const ValueType &valueType = ValueType::parseDecl(parent->next(), settings);
|
||||||
} else .. */
|
if (valueType.pointer)
|
||||||
|
setTokenValue(parent,value,settings);
|
||||||
|
else if (valueType.type == ValueType::Type::CHAR)
|
||||||
|
setTokenValue(parent, castValue(value, valueType.sign, settings->char_bit), settings);
|
||||||
|
else if (valueType.type == ValueType::Type::SHORT)
|
||||||
|
setTokenValue(parent, castValue(value, valueType.sign, settings->short_bit), settings);
|
||||||
|
else if (valueType.type == ValueType::Type::INT)
|
||||||
|
setTokenValue(parent, castValue(value, valueType.sign, settings->int_bit), settings);
|
||||||
|
else if (valueType.type == ValueType::Type::LONG)
|
||||||
|
setTokenValue(parent, castValue(value, valueType.sign, settings->long_bit), settings);
|
||||||
|
else if (valueType.type == ValueType::Type::LONGLONG)
|
||||||
|
setTokenValue(parent, castValue(value, valueType.sign, settings->long_long_bit), settings);
|
||||||
|
}
|
||||||
|
|
||||||
if (parent->str() == ":") {
|
else if (parent->str() == ":") {
|
||||||
setTokenValue(parent,value,settings);
|
setTokenValue(parent,value,settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ private:
|
||||||
check("void foo() {\n"
|
check("void foo() {\n"
|
||||||
" cout << 42 / (int)0;\n"
|
" cout << 42 / (int)0;\n"
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", "", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Division by zero.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void zeroDiv2() {
|
void zeroDiv2() {
|
||||||
|
|
|
@ -378,8 +378,10 @@ private:
|
||||||
ASSERT_EQUALS(0, valueOfTok("3 <= (a ? b : 2);", "<=").intvalue);
|
ASSERT_EQUALS(0, valueOfTok("3 <= (a ? b : 2);", "<=").intvalue);
|
||||||
|
|
||||||
ASSERT(tokenValues("(UNKNOWN_TYPE)123;","(").empty());
|
ASSERT(tokenValues("(UNKNOWN_TYPE)123;","(").empty());
|
||||||
ASSERT(tokenValues("(unsigned char)~0;", "(").empty()); // TODO: should get value 255
|
ASSERT_EQUALS(255, valueOfTok("(unsigned char)~0;", "(").intvalue);
|
||||||
ASSERT(tokenValues("(int)0;", "(").empty()); // TODO: should get value 0
|
ASSERT_EQUALS(0, valueOfTok("(int)0;", "(").intvalue);
|
||||||
|
ASSERT_EQUALS(0, valueOfTok("(UNKNOWN_TYPE*)0;","(").intvalue);
|
||||||
|
ASSERT_EQUALS(100, valueOfTok("(int)100.0;", "(").intvalue);
|
||||||
|
|
||||||
// Don't calculate if there is UB
|
// Don't calculate if there is UB
|
||||||
ASSERT(tokenValues(";-1<<10;","<<").empty());
|
ASSERT(tokenValues(";-1<<10;","<<").empty());
|
||||||
|
|
Loading…
Reference in New Issue