mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Subtraction for unsigned integers.
This commit is contained in:
parent
5e5138869b
commit
45ee3fc007
@ -360,6 +360,22 @@ string YulUtilFunctions::overflowCheckedUIntAddFunction(size_t _bits)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string YulUtilFunctions::overflowCheckedUIntSubFunction()
|
||||||
|
{
|
||||||
|
string functionName = "checked_sub_uint";
|
||||||
|
return m_functionCollector->createFunction(functionName, [&] {
|
||||||
|
return
|
||||||
|
Whiskers(R"(
|
||||||
|
function <functionName>(x, y) -> diff {
|
||||||
|
if lt(x, y) { revert(0, 0) }
|
||||||
|
diff := sub(x, y)
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
("functionName", functionName)
|
||||||
|
.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
string YulUtilFunctions::arrayLengthFunction(ArrayType const& _type)
|
string YulUtilFunctions::arrayLengthFunction(ArrayType const& _type)
|
||||||
{
|
{
|
||||||
string functionName = "array_length_" + _type.identifier();
|
string functionName = "array_length_" + _type.identifier();
|
||||||
|
@ -86,6 +86,10 @@ public:
|
|||||||
|
|
||||||
std::string overflowCheckedUIntAddFunction(size_t _bits);
|
std::string overflowCheckedUIntAddFunction(size_t _bits);
|
||||||
|
|
||||||
|
/// @returns computes the difference between two values.
|
||||||
|
/// Assumes the input to be in range for the type.
|
||||||
|
std::string overflowCheckedUIntSubFunction();
|
||||||
|
|
||||||
std::string arrayLengthFunction(ArrayType const& _type);
|
std::string arrayLengthFunction(ArrayType const& _type);
|
||||||
/// @returns the name of a function that computes the number of bytes required
|
/// @returns the name of a function that computes the number of bytes required
|
||||||
/// to store an array in memory given its length (internally encoded, not ABI encoded).
|
/// to store an array in memory given its length (internally encoded, not ABI encoded).
|
||||||
|
@ -292,17 +292,19 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
solUnimplementedAssert(_binOp.getOperator() == Token::Add, "");
|
|
||||||
if (IntegerType const* type = dynamic_cast<IntegerType const*>(commonType))
|
if (IntegerType const* type = dynamic_cast<IntegerType const*>(commonType))
|
||||||
{
|
{
|
||||||
solUnimplementedAssert(!type->isSigned(), "");
|
solUnimplementedAssert(!type->isSigned(), "");
|
||||||
defineExpression(_binOp) <<
|
string left = expressionAsType(_binOp.leftExpression(), *commonType);
|
||||||
m_utils.overflowCheckedUIntAddFunction(type->numBits()) <<
|
string right = expressionAsType(_binOp.rightExpression(), *commonType);
|
||||||
"(" <<
|
string fun;
|
||||||
expressionAsType(_binOp.leftExpression(), *commonType) <<
|
if (_binOp.getOperator() == Token::Add)
|
||||||
", " <<
|
fun = m_utils.overflowCheckedUIntAddFunction(type->numBits());
|
||||||
expressionAsType(_binOp.rightExpression(), *commonType) <<
|
else if (_binOp.getOperator() == Token::Sub)
|
||||||
")\n";
|
fun = m_utils.overflowCheckedUIntSubFunction();
|
||||||
|
else
|
||||||
|
solUnimplementedAssert(false, "");
|
||||||
|
defineExpression(_binOp) << fun << "(" << left << ", " << right << ")\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
solUnimplementedAssert(false, "");
|
solUnimplementedAssert(false, "");
|
||||||
|
Loading…
Reference in New Issue
Block a user