Skip to content

Commit 6b99162

Browse files
authored
Merge pull request #13406 from ethereum/slot_on_reference_fix
Fix `.slot` accessing via mapping reference in assembly
2 parents 5192965 + cf3bae0 commit 6b99162

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

libsolidity/ast/Types.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3789,6 +3789,11 @@ TypeResult MappingType::interfaceType(bool _inLibrary) const
37893789
return this;
37903790
}
37913791

3792+
std::vector<std::tuple<std::string, Type const*>> MappingType::makeStackItems() const
3793+
{
3794+
return {std::make_tuple("slot", TypeProvider::uint256())};
3795+
}
3796+
37923797
string TypeType::richIdentifier() const
37933798
{
37943799
return "t_type" + identifierList(actualType());

libsolidity/ast/Types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,8 @@ class MappingType: public CompositeType
15281528
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
15291529
bool nameable() const override { return true; }
15301530

1531+
std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
1532+
15311533
Type const* keyType() const { return m_keyType; }
15321534
Type const* valueType() const { return m_valueType; }
15331535

libsolidity/codegen/ir/IRGeneratorForStatements.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,9 @@ struct CopyTranslate: public yul::ASTCopier
173173
{
174174
solAssert(suffix == "slot" || suffix == "offset");
175175
solAssert(varDecl->isLocalVariable());
176+
solAssert(!varDecl->type()->isValueType());
176177
if (suffix == "slot")
177178
value = IRVariable{*varDecl}.part("slot").name();
178-
else if (varDecl->type()->isValueType())
179-
value = IRVariable{*varDecl}.part("offset").name();
180179
else
181180
{
182181
solAssert(!IRVariable{*varDecl}.hasPart("offset"));
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
contract C {
2+
mapping(uint => uint) private m0;
3+
mapping(uint => uint) private m1;
4+
mapping(uint => uint) private m2;
5+
6+
function f(uint i) public returns (uint slot, uint offset) {
7+
mapping(uint => uint) storage m0Ptr = m0;
8+
mapping(uint => uint) storage m1Ptr = m1;
9+
mapping(uint => uint) storage m2Ptr = m2;
10+
11+
assembly {
12+
switch i
13+
case 1 {
14+
slot := m1Ptr.slot
15+
offset := m1Ptr.offset
16+
}
17+
case 2 {
18+
slot := m2Ptr.slot
19+
offset := m2Ptr.offset
20+
}
21+
default {
22+
slot := m0Ptr.slot
23+
offset := m0Ptr.offset
24+
}
25+
}
26+
}
27+
}
28+
29+
// ----
30+
// f(uint256): 0 -> 0, 0
31+
// f(uint256): 1 -> 1, 0
32+
// f(uint256): 2 -> 2, 0

0 commit comments

Comments
 (0)