mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Remove handling of signed shift amounts.
This commit is contained in:
parent
ef49906f94
commit
1b810d4a0a
@ -2117,7 +2117,6 @@ void ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _v
|
|||||||
solAssert(dynamic_cast<FixedBytesType const*>(&_valueType), "Only integer and fixed bytes type supported for shifts.");
|
solAssert(dynamic_cast<FixedBytesType const*>(&_valueType), "Only integer and fixed bytes type supported for shifts.");
|
||||||
|
|
||||||
// The amount can be a RationalNumberType too.
|
// The amount can be a RationalNumberType too.
|
||||||
bool c_amountSigned = false;
|
|
||||||
if (auto amountType = dynamic_cast<RationalNumberType const*>(&_shiftAmountType))
|
if (auto amountType = dynamic_cast<RationalNumberType const*>(&_shiftAmountType))
|
||||||
{
|
{
|
||||||
// This should be handled by the type checker.
|
// This should be handled by the type checker.
|
||||||
@ -2125,17 +2124,10 @@ void ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _v
|
|||||||
solAssert(!amountType->integerType()->isSigned(), "");
|
solAssert(!amountType->integerType()->isSigned(), "");
|
||||||
}
|
}
|
||||||
else if (auto amountType = dynamic_cast<IntegerType const*>(&_shiftAmountType))
|
else if (auto amountType = dynamic_cast<IntegerType const*>(&_shiftAmountType))
|
||||||
c_amountSigned = amountType->isSigned();
|
solAssert(!amountType->isSigned(), "");
|
||||||
else
|
else
|
||||||
solAssert(false, "Invalid shift amount type.");
|
solAssert(false, "Invalid shift amount type.");
|
||||||
|
|
||||||
// shift by negative amount throws exception
|
|
||||||
if (c_amountSigned)
|
|
||||||
{
|
|
||||||
m_context << u256(0) << Instruction::DUP3 << Instruction::SLT;
|
|
||||||
m_context.appendConditionalInvalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_context << Instruction::SWAP1;
|
m_context << Instruction::SWAP1;
|
||||||
// stack: value_to_shift shift_amount
|
// stack: value_to_shift shift_amount
|
||||||
|
|
||||||
|
@ -347,20 +347,17 @@ string YulUtilFunctions::typedShiftLeftFunction(Type const& _type, Type const& _
|
|||||||
{
|
{
|
||||||
solAssert(_type.category() == Type::Category::FixedBytes || _type.category() == Type::Category::Integer, "");
|
solAssert(_type.category() == Type::Category::FixedBytes || _type.category() == Type::Category::Integer, "");
|
||||||
solAssert(_amountType.category() == Type::Category::Integer, "");
|
solAssert(_amountType.category() == Type::Category::Integer, "");
|
||||||
|
solAssert(!dynamic_cast<IntegerType const&>(_amountType).isSigned(), "");
|
||||||
string const functionName = "shift_left_" + _type.identifier() + "_" + _amountType.identifier();
|
string const functionName = "shift_left_" + _type.identifier() + "_" + _amountType.identifier();
|
||||||
return m_functionCollector.createFunction(functionName, [&]() {
|
return m_functionCollector.createFunction(functionName, [&]() {
|
||||||
return
|
return
|
||||||
Whiskers(R"(
|
Whiskers(R"(
|
||||||
function <functionName>(value, bits) -> result {
|
function <functionName>(value, bits) -> result {
|
||||||
bits := <cleanAmount>(bits)
|
bits := <cleanAmount>(bits)
|
||||||
<?amountSigned>
|
|
||||||
if slt(bits, 0) { invalid() }
|
|
||||||
</amountSigned>
|
|
||||||
result := <cleanup>(<shift>(bits, value))
|
result := <cleanup>(<shift>(bits, value))
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("amountSigned", dynamic_cast<IntegerType const&>(_amountType).isSigned())
|
|
||||||
("cleanAmount", cleanupFunction(_amountType))
|
("cleanAmount", cleanupFunction(_amountType))
|
||||||
("shift", shiftLeftFunctionDynamic())
|
("shift", shiftLeftFunctionDynamic())
|
||||||
("cleanup", cleanupFunction(_type))
|
("cleanup", cleanupFunction(_type))
|
||||||
@ -372,6 +369,7 @@ string YulUtilFunctions::typedShiftRightFunction(Type const& _type, Type const&
|
|||||||
{
|
{
|
||||||
solAssert(_type.category() == Type::Category::FixedBytes || _type.category() == Type::Category::Integer, "");
|
solAssert(_type.category() == Type::Category::FixedBytes || _type.category() == Type::Category::Integer, "");
|
||||||
solAssert(_amountType.category() == Type::Category::Integer, "");
|
solAssert(_amountType.category() == Type::Category::Integer, "");
|
||||||
|
solAssert(!dynamic_cast<IntegerType const&>(_amountType).isSigned(), "");
|
||||||
IntegerType const* integerType = dynamic_cast<IntegerType const*>(&_type);
|
IntegerType const* integerType = dynamic_cast<IntegerType const*>(&_type);
|
||||||
bool valueSigned = integerType && integerType->isSigned();
|
bool valueSigned = integerType && integerType->isSigned();
|
||||||
|
|
||||||
@ -381,14 +379,10 @@ string YulUtilFunctions::typedShiftRightFunction(Type const& _type, Type const&
|
|||||||
Whiskers(R"(
|
Whiskers(R"(
|
||||||
function <functionName>(value, bits) -> result {
|
function <functionName>(value, bits) -> result {
|
||||||
bits := <cleanAmount>(bits)
|
bits := <cleanAmount>(bits)
|
||||||
<?amountSigned>
|
|
||||||
if slt(bits, 0) { invalid() }
|
|
||||||
</amountSigned>
|
|
||||||
result := <cleanup>(<shift>(bits, <cleanup>(value)))
|
result := <cleanup>(<shift>(bits, <cleanup>(value)))
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("amountSigned", dynamic_cast<IntegerType const&>(_amountType).isSigned())
|
|
||||||
("cleanAmount", cleanupFunction(_amountType))
|
("cleanAmount", cleanupFunction(_amountType))
|
||||||
("shift", valueSigned ? shiftRightSignedFunctionDynamic() : shiftRightFunctionDynamic())
|
("shift", valueSigned ? shiftRightSignedFunctionDynamic() : shiftRightFunctionDynamic())
|
||||||
("cleanup", cleanupFunction(_type))
|
("cleanup", cleanupFunction(_type))
|
||||||
|
Loading…
Reference in New Issue
Block a user