Fixed #6317 (wrong simplification: int i = 1.5; return i; get simplified to: return 1.5;)

This commit is contained in:
Daniel Marjamäki 2019-05-01 17:05:16 +02:00
parent 1cc5f3abe7
commit 6c3c090403
2 changed files with 44 additions and 1 deletions

View File

@ -3564,6 +3564,30 @@ static void valueFlowForwardAssign(Token * const tok,
valueFlowForward(const_cast<Token *>(nextExpression), endOfVarScope, var, var->declarationId(), values, constValue, false, tokenlist, errorLogger, settings);
}
static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> values, const ValueType *valueType, const Settings *settings)
{
if (!valueType || !valueType->isIntegral())
return values;
const size_t sz = getSizeOf(*valueType, settings);
for (ValueFlow::Value &value : values) {
if (value.isFloatValue()) {
value.intvalue = value.floatValue;
value.valueType = ValueFlow::Value::INT;
}
if (value.isIntValue() && sz > 0 && sz < 8) {
const MathLib::biguint unsignedMaxValue = (1ULL << (sz * 8)) - 1ULL;
const MathLib::biguint signBit = 1ULL << (sz * 8 - 1);
value.intvalue &= unsignedMaxValue;
if (valueType->sign == ValueType::Sign::SIGNED && (value.intvalue & signBit))
value.intvalue |= ~unsignedMaxValue;
}
}
return values;
}
static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
for (const Scope * scope : symboldatabase->functionScopes) {
@ -3593,7 +3617,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
if (!tok->astOperand2() || tok->astOperand2()->values().empty())
continue;
std::list<ValueFlow::Value> values = tok->astOperand2()->values();
std::list<ValueFlow::Value> values = truncateValues(tok->astOperand2()->values(), tok->astOperand1()->valueType(), settings);
const bool constValue = tok->astOperand2()->isNumber();
const bool init = var->nameToken() == tok->astOperand1();
valueFlowForwardAssign(const_cast<Token *>(tok->astOperand2()), var, values, constValue, init, tokenlist, errorLogger, settings);

View File

@ -1443,6 +1443,25 @@ private:
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
// truncation
code = "int f() {\n"
" int x = 1.5;\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 1));
code = "int f() {\n"
" unsigned char x = 0x123;\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0x23));
code = "int f() {\n"
" signed char x = 0xfe;\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, -2));
// function
code = "void f() {\n"
" char *x = 0;\n"