ExprEngine: Extended value truncation

This commit is contained in:
Daniel Marjamäki 2019-09-24 13:27:53 +02:00
parent 5615da4547
commit ba035074f0
1 changed files with 15 additions and 11 deletions

View File

@ -495,6 +495,8 @@ static ExprEngine::ValuePtr executeReturn(const Token *tok, Data &data)
static ExprEngine::ValuePtr truncateValue(ExprEngine::ValuePtr val, const ValueType *valueType, Data &data) static ExprEngine::ValuePtr truncateValue(ExprEngine::ValuePtr val, const ValueType *valueType, Data &data)
{ {
if (!valueType)
return val;
if (valueType->pointer != 0) if (valueType->pointer != 0)
return val; return val;
if (!valueType->isIntegral()) if (!valueType->isIntegral())
@ -532,29 +534,31 @@ static ExprEngine::ValuePtr truncateValue(ExprEngine::ValuePtr val, const ValueT
static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data) static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data)
{ {
ExprEngine::ValuePtr rhsValue = executeExpression(tok->astOperand2(), data); ExprEngine::ValuePtr rhsValue = executeExpression(tok->astOperand2(), data);
ExprEngine::ValuePtr assignValue;
if (tok->str() == "=") if (tok->str() == "=")
call(data.callbacks, tok, rhsValue); assignValue = rhsValue;
else { else {
// "+=" => "+" // "+=" => "+"
std::string binop(tok->str()); std::string binop(tok->str());
binop = binop.substr(0, binop.size() - 1); binop = binop.substr(0, binop.size() - 1);
ExprEngine::ValuePtr lhsValue = executeExpression(tok->astOperand1(), data); ExprEngine::ValuePtr lhsValue = executeExpression(tok->astOperand1(), data);
auto newValue = std::make_shared<ExprEngine::BinOpResult>(binop, lhsValue, rhsValue); assignValue = std::make_shared<ExprEngine::BinOpResult>(binop, lhsValue, rhsValue);
call(data.callbacks, tok, newValue);
rhsValue = newValue;
} }
const Token *lhsToken = tok->astOperand1(); const Token *lhsToken = tok->astOperand1();
data.trackAssignment(lhsToken, rhsValue); assignValue = truncateValue(assignValue, lhsToken->valueType(), data);
call(data.callbacks, tok, assignValue);
data.trackAssignment(lhsToken, assignValue);
if (lhsToken->varId() > 0) { if (lhsToken->varId() > 0) {
data.memory[lhsToken->varId()] = truncateValue(rhsValue, lhsToken->valueType(), data); data.memory[lhsToken->varId()] = assignValue;
} else if (lhsToken->str() == "[") { } else if (lhsToken->str() == "[") {
auto arrayValue = data.getArrayValue(lhsToken->astOperand1()); auto arrayValue = data.getArrayValue(lhsToken->astOperand1());
if (arrayValue) { if (arrayValue) {
// Is it array initialization? // Is it array initialization?
const Token *arrayInit = lhsToken->astOperand1(); const Token *arrayInit = lhsToken->astOperand1();
if (arrayInit && arrayInit->variable() && arrayInit->variable()->nameToken() == arrayInit) { if (arrayInit && arrayInit->variable() && arrayInit->variable()->nameToken() == arrayInit) {
if (auto strval = std::dynamic_pointer_cast<ExprEngine::StringLiteralValue>(rhsValue)) { if (auto strval = std::dynamic_pointer_cast<ExprEngine::StringLiteralValue>(assignValue)) {
for (size_t i = 0; i < strval->size(); ++i) { for (size_t i = 0; i < strval->size(); ++i) {
uint8_t c = strval->string[i]; uint8_t c = strval->string[i];
arrayValue->data[i] = std::make_shared<ExprEngine::IntRange>(std::to_string(int(c)),c,c); arrayValue->data[i] = std::make_shared<ExprEngine::IntRange>(std::to_string(int(c)),c,c);
@ -565,7 +569,7 @@ static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data)
} }
} else { } else {
auto indexValue = executeExpression(lhsToken->astOperand2(), data); auto indexValue = executeExpression(lhsToken->astOperand2(), data);
arrayValue->assign(indexValue, rhsValue); arrayValue->assign(indexValue, assignValue);
} }
} }
} else if (lhsToken->isUnaryOp("*")) { } else if (lhsToken->isUnaryOp("*")) {
@ -573,7 +577,7 @@ static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data)
if (pval && pval->type() == ExprEngine::ValueType::AddressOfValue) { if (pval && pval->type() == ExprEngine::ValueType::AddressOfValue) {
auto val = std::dynamic_pointer_cast<ExprEngine::AddressOfValue>(pval); auto val = std::dynamic_pointer_cast<ExprEngine::AddressOfValue>(pval);
if (val) if (val)
data.memory[val->varId] = rhsValue; data.memory[val->varId] = assignValue;
} else if (pval && pval->type() == ExprEngine::ValueType::BinOpResult) { } else if (pval && pval->type() == ExprEngine::ValueType::BinOpResult) {
auto b = std::dynamic_pointer_cast<ExprEngine::BinOpResult>(pval); auto b = std::dynamic_pointer_cast<ExprEngine::BinOpResult>(pval);
if (b && b->binop == "+") { if (b && b->binop == "+") {
@ -587,12 +591,12 @@ static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data)
offset = b->op1; offset = b->op1;
} }
if (arr && offset) { if (arr && offset) {
arr->assign(offset, rhsValue); arr->assign(offset, assignValue);
} }
} }
} }
} }
return rhsValue; return assignValue;
} }
static ExprEngine::ValuePtr executeFunctionCall(const Token *tok, Data &data) static ExprEngine::ValuePtr executeFunctionCall(const Token *tok, Data &data)