Bugfix for constructor unpacking with fixed-size arrays.

This commit is contained in:
chriseth 2015-11-29 00:59:01 +01:00
parent c806b9bcdb
commit 6796afc2f8
2 changed files with 30 additions and 5 deletions

View File

@ -305,6 +305,8 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
// @todo If base type is an array or struct, it is still calldata-style encoded, so
// we would have to convert it like below.
solAssert(arrayType.location() == DataLocation::Memory, "");
if (arrayType.isDynamicallySized())
{
// compute data pointer
m_context << eth::Instruction::DUP1 << eth::Instruction::MLOAD;
m_context << eth::Instruction::DUP3 << eth::Instruction::ADD;
@ -312,6 +314,12 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
m_context << u256(0x20) << eth::Instruction::ADD;
}
else
{
m_context << eth::Instruction::DUP1;
m_context << u256(arrayType.calldataEncodedSize(true)) << eth::Instruction::ADD;
}
}
else
{
// first load from calldata and potentially convert to memory if arrayType is memory
TypePointer calldataType = arrayType.copyForLocation(DataLocation::CallData, false);

View File

@ -4671,6 +4671,23 @@ BOOST_AUTO_TEST_CASE(arrays_in_constructors)
);
}
BOOST_AUTO_TEST_CASE(fixed_arrays_in_constructors)
{
char const* sourceCode = R"(
contract Creator {
uint public r;
address public ch;
function Creator(address[3] s, uint x) {
r = x;
ch = s[2];
}
}
)";
compileAndRun(sourceCode, 0, "Creator", encodeArgs(u256(1), u256(2), u256(3), u256(4)));
BOOST_REQUIRE(callContractFunction("r()") == encodeArgs(u256(4)));
BOOST_REQUIRE(callContractFunction("ch()") == encodeArgs(u256(3)));
}
BOOST_AUTO_TEST_CASE(arrays_from_and_to_storage)
{
char const* sourceCode = R"(