Fixed #7872 (ValueFlow: static_cast)
This commit is contained in:
parent
6fef02498c
commit
a40fe3c67f
|
@ -372,6 +372,9 @@ static void combineValueProperties(const ValueFlow::Value &value1, const ValueFl
|
||||||
result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
|
result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set token value for cast */
|
||||||
|
static void setTokenValueCast(Token *parent, const ValueType &valueType, const ValueFlow::Value &value, const Settings *settings);
|
||||||
|
|
||||||
/** 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)
|
||||||
{
|
{
|
||||||
|
@ -438,28 +441,15 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cast..
|
||||||
if (parent->str() == "(" && !parent->astOperand2() && Token::Match(parent,"( %name%")) {
|
if (parent->str() == "(" && !parent->astOperand2() && Token::Match(parent,"( %name%")) {
|
||||||
const ValueType &valueType = ValueType::parseDecl(parent->next(), settings);
|
const ValueType &valueType = ValueType::parseDecl(parent->next(), settings);
|
||||||
if (valueType.pointer)
|
setTokenValueCast(parent, valueType, value, settings);
|
||||||
setTokenValue(parent,value,settings);
|
}
|
||||||
else if (valueType.type == ValueType::Type::CHAR)
|
|
||||||
setTokenValue(parent, castValue(value, valueType.sign, settings->char_bit), settings);
|
else if (parent->str() == "(" && parent->astOperand2() && Token::Match(parent->astOperand1(), "const_cast|dynamic_cast|reinterpret_cast|static_cast <")) {
|
||||||
else if (valueType.type == ValueType::Type::SHORT)
|
const ValueType &valueType = ValueType::parseDecl(parent->astOperand1()->tokAt(2), settings);
|
||||||
setTokenValue(parent, castValue(value, valueType.sign, settings->short_bit), settings);
|
setTokenValueCast(parent, valueType, value, 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);
|
|
||||||
else if (value.isIntValue()) {
|
|
||||||
const long long charMax = settings->signedCharMax();
|
|
||||||
const long long charMin = settings->signedCharMin();
|
|
||||||
if (charMin <= value.intvalue && value.intvalue <= charMax) {
|
|
||||||
// unknown type, but value is small so there should be no truncation etc
|
|
||||||
setTokenValue(parent,value,settings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (parent->str() == ":") {
|
else if (parent->str() == ":") {
|
||||||
|
@ -786,6 +776,30 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setTokenValueCast(Token *parent, const ValueType &valueType, const ValueFlow::Value &value, const Settings *settings)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
else if (value.isIntValue()) {
|
||||||
|
const long long charMax = settings->signedCharMax();
|
||||||
|
const long long charMin = settings->signedCharMin();
|
||||||
|
if (charMin <= value.intvalue && value.intvalue <= charMax) {
|
||||||
|
// unknown type, but value is small so there should be no truncation etc
|
||||||
|
setTokenValue(parent,value,settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int getSizeOfType(const Token *typeTok, const Settings *settings)
|
static unsigned int getSizeOfType(const Token *typeTok, const Settings *settings)
|
||||||
{
|
{
|
||||||
const std::string &typeStr = typeTok->str();
|
const std::string &typeStr = typeTok->str();
|
||||||
|
|
|
@ -537,6 +537,7 @@ private:
|
||||||
ASSERT_EQUALS(3, valueOfTok("(int)(1+2);", "(").intvalue);
|
ASSERT_EQUALS(3, valueOfTok("(int)(1+2);", "(").intvalue);
|
||||||
ASSERT_EQUALS(0, valueOfTok("(UNKNOWN_TYPE*)0;","(").intvalue);
|
ASSERT_EQUALS(0, valueOfTok("(UNKNOWN_TYPE*)0;","(").intvalue);
|
||||||
ASSERT_EQUALS(100, valueOfTok("(int)100.0;", "(").intvalue);
|
ASSERT_EQUALS(100, valueOfTok("(int)100.0;", "(").intvalue);
|
||||||
|
ASSERT_EQUALS(10, valueOfTok("x = static_cast<int>(10);", "( 10 )").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