Fix ICE when pop dyn storage array of mapping

This commit is contained in:
Leonardo Alt 2019-09-14 02:11:09 +02:00
parent 2d601a4f23
commit eab9f65610
4 changed files with 84 additions and 5 deletions

View File

@ -13,6 +13,7 @@ Compiler Features:
Bugfixes:
* Fix internal error when popping a dynamic storage array of mappings.
### 0.5.11 (2019-08-12)

View File

@ -896,11 +896,16 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const
// Stack: ArrayReference oldLength
m_context << u256(1) << Instruction::SWAP1 << Instruction::SUB;
// Stack ArrayReference newLength
m_context << Instruction::DUP2 << Instruction::DUP2;
// Stack ArrayReference newLength ArrayReference newLength;
accessIndex(_type, false);
// Stack: ArrayReference newLength storage_slot byte_offset
StorageItem(m_context, *_type.baseType()).setToZero(SourceLocation(), true);
if (_type.baseType()->category() != Type::Category::Mapping)
{
m_context << Instruction::DUP2 << Instruction::DUP2;
// Stack ArrayReference newLength ArrayReference newLength;
accessIndex(_type, false);
// Stack: ArrayReference newLength storage_slot byte_offset
StorageItem(m_context, *_type.baseType()).setToZero(SourceLocation(), true);
}
// Stack: ArrayReference newLength
m_context << Instruction::SWAP1 << Instruction::SSTORE;
}

View File

@ -0,0 +1,39 @@
contract C {
mapping (uint => uint)[][] a;
function n1(uint key, uint value) public {
a.length++;
mapping (uint => uint)[] storage b = a[a.length - 1];
b.length++;
b[b.length - 1][key] = value;
}
function n2() public {
a.length++;
mapping (uint => uint)[] storage b = a[a.length - 1];
b.length++;
}
function map(uint key) public view returns (uint) {
mapping (uint => uint)[] storage b = a[a.length - 1];
return b[b.length - 1][key];
}
function p() public {
a.pop();
}
function d() public returns (uint) {
delete a;
return a.length;
}
}
// ----
// n1(uint256,uint256): 42, 64 ->
// map(uint256): 42 -> 64
// p() ->
// n2() ->
// map(uint256): 42 -> 64
// d() -> 0
// n2() ->
// map(uint256): 42 -> 64

View File

@ -0,0 +1,34 @@
contract C {
mapping (uint => uint)[] a;
function n1(uint key, uint value) public {
a.length++;
a[a.length - 1][key] = value;
}
function n2() public {
a.length++;
}
function map(uint key) public view returns (uint) {
return a[a.length - 1][key];
}
function p() public {
a.pop();
}
function d() public returns (uint) {
delete a;
return a.length;
}
}
// ----
// n1(uint256,uint256): 42, 64 ->
// map(uint256): 42 -> 64
// p() ->
// n2() ->
// map(uint256): 42 -> 64
// d() -> 0
// n2() ->
// map(uint256): 42 -> 64