Skip to content

Commit da5c592

Browse files
committed
Properly handle fixed-byte-like types.
1 parent 6109b5c commit da5c592

4 files changed

Lines changed: 20 additions & 14 deletions

File tree

libsolidity/ast/Types.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,6 +2537,7 @@ Type const& UserDefinedValueType::underlyingType() const
25372537
{
25382538
Type const* type = m_definition.underlyingType()->annotation().type;
25392539
solAssert(type, "");
2540+
solAssert(type->category() != Category::UserDefinedValueType, "");
25402541
return *type;
25412542
}
25422543

libsolidity/codegen/CompilerUtils.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,10 +1552,13 @@ void CompilerUtils::storeStringData(bytesConstRef _data)
15521552
unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWords)
15531553
{
15541554
solAssert(_type.isValueType(), "");
1555+
Type const* type = &_type;
1556+
if (auto const* userDefined = dynamic_cast<UserDefinedValueType const*>(type))
1557+
type = &userDefined->underlyingType();
15551558

1556-
unsigned numBytes = _type.calldataEncodedSize(_padToWords);
1559+
unsigned numBytes = type->calldataEncodedSize(_padToWords);
15571560
bool isExternalFunctionType = false;
1558-
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
1561+
if (auto const* funType = dynamic_cast<FunctionType const*>(type))
15591562
if (funType->kind() == FunctionType::Kind::External)
15601563
isExternalFunctionType = true;
15611564
if (numBytes == 0)
@@ -1570,21 +1573,20 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda
15701573
splitExternalFunctionType(true);
15711574
else if (numBytes != 32)
15721575
{
1573-
bool leftAligned = _type.category() == Type::Category::FixedBytes;
15741576
// add leading or trailing zeros by dividing/multiplying depending on alignment
15751577
unsigned shiftFactor = (32 - numBytes) * 8;
15761578
rightShiftNumberOnStack(shiftFactor);
1577-
if (leftAligned)
1579+
if (type->leftAligned())
15781580
{
15791581
leftShiftNumberOnStack(shiftFactor);
15801582
cleanupNeeded = false;
15811583
}
1582-
else if (IntegerType const* intType = dynamic_cast<IntegerType const*>(&_type))
1584+
else if (IntegerType const* intType = dynamic_cast<IntegerType const*>(type))
15831585
if (!intType->isSigned())
15841586
cleanupNeeded = false;
15851587
}
15861588
if (_fromCalldata)
1587-
convertType(_type, _type, cleanupNeeded, false, true);
1589+
convertType(_type, *type, cleanupNeeded, false, true);
15881590

15891591
return numBytes;
15901592
}
@@ -1639,12 +1641,10 @@ unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords,
16391641
"Memory store of more than 32 bytes requested (Type: " + _type.toString(true) + ")."
16401642
);
16411643

1642-
bool leftAligned = _type.category() == Type::Category::FixedBytes;
1643-
16441644
if (_cleanup)
16451645
convertType(_type, _type, true);
16461646

1647-
if (numBytes != 32 && !leftAligned && !_padToWords)
1647+
if (numBytes != 32 && !_type.leftAligned() && !_padToWords)
16481648
// shift the value accordingly before storing
16491649
leftShiftNumberOnStack((32 - numBytes) * 8);
16501650

libsolidity/codegen/LValue.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ void MemoryItem::storeValue(Type const& _sourceType, SourceLocation const&, bool
113113
if (!m_padded)
114114
{
115115
solAssert(m_dataType->calldataEncodedSize(false) == 1, "Invalid non-padded type.");
116+
solAssert(m_dataType->category() != Type::Category::UserDefinedValueType, "");
116117
if (m_dataType->category() == Type::Category::FixedBytes)
117118
m_context << u256(0) << Instruction::BYTE;
118119
m_context << Instruction::SWAP1 << Instruction::MSTORE8;
@@ -233,7 +234,7 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
233234
if (m_dataType->category() == Type::Category::FixedPoint)
234235
// implementation should be very similar to the integer case.
235236
solUnimplemented("Not yet implemented - FixedPointType.");
236-
if (m_dataType->category() == Type::Category::FixedBytes)
237+
if (m_dataType->leftAligned())
237238
{
238239
CompilerUtils(m_context).leftShiftNumberOnStack(256 - 8 * m_dataType->storageBytes());
239240
cleaned = true;
@@ -329,10 +330,13 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
329330
Instruction::AND;
330331
}
331332
}
332-
else if (m_dataType->category() == Type::Category::FixedBytes)
333+
else if (m_dataType->leftAligned())
333334
{
334-
solAssert(_sourceType.category() == Type::Category::FixedBytes, "source not fixed bytes");
335-
CompilerUtils(m_context).rightShiftNumberOnStack(256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes());
335+
solAssert(_sourceType.category() == Type::Category::FixedBytes || (
336+
_sourceType.encodingType() &&
337+
_sourceType.encodingType()->category() == Type::Category::FixedBytes
338+
), "source not fixed bytes");
339+
CompilerUtils(m_context).rightShiftNumberOnStack(256 - 8 * m_dataType->storageBytes());
336340
}
337341
else
338342
{

libsolidity/codegen/YulUtilFunctions.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2965,7 +2965,7 @@ string YulUtilFunctions::prepareStoreFunction(Type const& _type)
29652965
}
29662966
)");
29672967
templ("functionName", functionName);
2968-
if (_type.category() == Type::Category::FixedBytes)
2968+
if (_type.leftAligned())
29692969
templ("actualPrepare", shiftRightFunction(256 - 8 * _type.storageBytes()) + "(value)");
29702970
else
29712971
templ("actualPrepare", "value");
@@ -3304,6 +3304,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
33043304
bodyTemplate("cleanOutput", cleanupFunction(_to));
33053305
string convert;
33063306

3307+
solAssert(_to.category() != Type::Category::UserDefinedValueType, "");
33073308
if (auto const* toFixedBytes = dynamic_cast<FixedBytesType const*>(&_to))
33083309
convert = shiftLeftFunction(256 - toFixedBytes->numBytes() * 8);
33093310
else if (dynamic_cast<FixedPointType const*>(&_to))

0 commit comments

Comments
 (0)