Merge pull request #13406 from ethereum/slot_on_reference_fix

Fix `.slot` accessing via mapping reference in assembly
This commit is contained in:
Damian Wechman 2022-09-05 14:00:18 +02:00 committed by GitHub
commit 6b99162457
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 2 deletions

View File

@ -3789,6 +3789,11 @@ TypeResult MappingType::interfaceType(bool _inLibrary) const
return this;
}
std::vector<std::tuple<std::string, Type const*>> MappingType::makeStackItems() const
{
return {std::make_tuple("slot", TypeProvider::uint256())};
}
string TypeType::richIdentifier() const
{
return "t_type" + identifierList(actualType());

View File

@ -1528,6 +1528,8 @@ public:
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
bool nameable() const override { return true; }
std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
Type const* keyType() const { return m_keyType; }
Type const* valueType() const { return m_valueType; }

View File

@ -173,10 +173,9 @@ private:
{
solAssert(suffix == "slot" || suffix == "offset");
solAssert(varDecl->isLocalVariable());
solAssert(!varDecl->type()->isValueType());
if (suffix == "slot")
value = IRVariable{*varDecl}.part("slot").name();
else if (varDecl->type()->isValueType())
value = IRVariable{*varDecl}.part("offset").name();
else
{
solAssert(!IRVariable{*varDecl}.hasPart("offset"));

View File

@ -0,0 +1,32 @@
contract C {
mapping(uint => uint) private m0;
mapping(uint => uint) private m1;
mapping(uint => uint) private m2;
function f(uint i) public returns (uint slot, uint offset) {
mapping(uint => uint) storage m0Ptr = m0;
mapping(uint => uint) storage m1Ptr = m1;
mapping(uint => uint) storage m2Ptr = m2;
assembly {
switch i
case 1 {
slot := m1Ptr.slot
offset := m1Ptr.offset
}
case 2 {
slot := m2Ptr.slot
offset := m2Ptr.offset
}
default {
slot := m0Ptr.slot
offset := m0Ptr.offset
}
}
}
}
// ----
// f(uint256): 0 -> 0, 0
// f(uint256): 1 -> 1, 0
// f(uint256): 2 -> 2, 0