mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix signextend for user defined value types.
This commit is contained in:
parent
7b7e38768c
commit
cb052611cf
@ -227,27 +227,30 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
|
|||||||
m_context << Instruction::POP << Instruction::SLOAD;
|
m_context << Instruction::POP << Instruction::SLOAD;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Type const* type = m_dataType;
|
||||||
|
if (type->category() == Type::Category::UserDefinedValueType)
|
||||||
|
type = type->encodingType();
|
||||||
bool cleaned = false;
|
bool cleaned = false;
|
||||||
m_context
|
m_context
|
||||||
<< Instruction::SWAP1 << Instruction::SLOAD << Instruction::SWAP1
|
<< Instruction::SWAP1 << Instruction::SLOAD << Instruction::SWAP1
|
||||||
<< u256(0x100) << Instruction::EXP << Instruction::SWAP1 << Instruction::DIV;
|
<< u256(0x100) << Instruction::EXP << Instruction::SWAP1 << Instruction::DIV;
|
||||||
if (m_dataType->category() == Type::Category::FixedPoint)
|
if (type->category() == Type::Category::FixedPoint)
|
||||||
// implementation should be very similar to the integer case.
|
// implementation should be very similar to the integer case.
|
||||||
solUnimplemented("Not yet implemented - FixedPointType.");
|
solUnimplemented("Not yet implemented - FixedPointType.");
|
||||||
if (m_dataType->leftAligned())
|
if (type->leftAligned())
|
||||||
{
|
{
|
||||||
CompilerUtils(m_context).leftShiftNumberOnStack(256 - 8 * m_dataType->storageBytes());
|
CompilerUtils(m_context).leftShiftNumberOnStack(256 - 8 * type->storageBytes());
|
||||||
cleaned = true;
|
cleaned = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
m_dataType->category() == Type::Category::Integer &&
|
type->category() == Type::Category::Integer &&
|
||||||
dynamic_cast<IntegerType const&>(*m_dataType).isSigned()
|
dynamic_cast<IntegerType const&>(*type).isSigned()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_context << u256(m_dataType->storageBytes() - 1) << Instruction::SIGNEXTEND;
|
m_context << u256(type->storageBytes() - 1) << Instruction::SIGNEXTEND;
|
||||||
cleaned = true;
|
cleaned = true;
|
||||||
}
|
}
|
||||||
else if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType))
|
else if (FunctionType const* fun = dynamic_cast<decltype(fun)>(type))
|
||||||
{
|
{
|
||||||
if (fun->kind() == FunctionType::Kind::External)
|
if (fun->kind() == FunctionType::Kind::External)
|
||||||
{
|
{
|
||||||
@ -263,8 +266,8 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
|
|||||||
}
|
}
|
||||||
if (!cleaned)
|
if (!cleaned)
|
||||||
{
|
{
|
||||||
solAssert(m_dataType->sizeOnStack() == 1, "");
|
solAssert(type->sizeOnStack() == 1, "");
|
||||||
m_context << ((u256(0x1) << (8 * m_dataType->storageBytes())) - 1) << Instruction::AND;
|
m_context << ((u256(0x1) << (8 * type->storageBytes())) - 1) << Instruction::AND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2912,9 +2912,12 @@ string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type)
|
|||||||
)");
|
)");
|
||||||
templ("functionName", functionName);
|
templ("functionName", functionName);
|
||||||
|
|
||||||
unsigned storageBytes = _type.storageBytes();
|
Type const* encodingType = &_type;
|
||||||
if (IntegerType const* type = dynamic_cast<IntegerType const*>(&_type))
|
if (_type.category() == Type::Category::UserDefinedValueType)
|
||||||
if (type->isSigned() && storageBytes != 32)
|
encodingType = _type.encodingType();
|
||||||
|
unsigned storageBytes = encodingType->storageBytes();
|
||||||
|
if (IntegerType const* intType = dynamic_cast<IntegerType const*>(encodingType))
|
||||||
|
if (intType->isSigned() && storageBytes != 32)
|
||||||
{
|
{
|
||||||
templ("cleaned", "signextend(" + to_string(storageBytes - 1) + ", value)");
|
templ("cleaned", "signextend(" + to_string(storageBytes - 1) + ", value)");
|
||||||
return templ.render();
|
return templ.render();
|
||||||
@ -2922,10 +2925,10 @@ string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type)
|
|||||||
|
|
||||||
bool leftAligned = false;
|
bool leftAligned = false;
|
||||||
if (
|
if (
|
||||||
_type.category() != Type::Category::Function ||
|
encodingType->category() != Type::Category::Function ||
|
||||||
dynamic_cast<FunctionType const&>(_type).kind() == FunctionType::Kind::External
|
dynamic_cast<FunctionType const&>(*encodingType).kind() == FunctionType::Kind::External
|
||||||
)
|
)
|
||||||
leftAligned = _type.leftAligned();
|
leftAligned = encodingType->leftAligned();
|
||||||
|
|
||||||
if (storageBytes == 32)
|
if (storageBytes == 32)
|
||||||
templ("cleaned", "value");
|
templ("cleaned", "value");
|
||||||
|
Loading…
Reference in New Issue
Block a user