Merge pull request #756 from chriseth/alloczero

Bugfix: Allocate empty array.
This commit is contained in:
chriseth 2016-07-29 16:58:25 +02:00 committed by GitHub
commit 56727d61a6
3 changed files with 21 additions and 3 deletions

View File

@ -104,6 +104,7 @@ public:
); );
/// Zero-initialises (the data part of) an already allocated memory array. /// Zero-initialises (the data part of) an already allocated memory array.
/// Length has to be nonzero!
/// Stack pre: <length> <memptr> /// Stack pre: <length> <memptr>
/// Stack post: <updated_memptr> /// Stack post: <updated_memptr>
void zeroInitialiseMemoryArray(ArrayType const& _type); void zeroInitialiseMemoryArray(ArrayType const& _type);

View File

@ -792,15 +792,18 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
utils().storeFreeMemoryPointer(); utils().storeFreeMemoryPointer();
// Stack: memptr requested_length // Stack: memptr requested_length
// Check if length is zero
m_context << Instruction::DUP1 << Instruction::ISZERO;
auto skipInit = m_context.appendConditionalJump();
// We only have to initialise if the base type is a not a value type. // We only have to initialise if the base type is a not a value type.
if (dynamic_cast<ReferenceType const*>(arrayType.baseType().get())) if (dynamic_cast<ReferenceType const*>(arrayType.baseType().get()))
{ {
m_context << Instruction::DUP2 << u256(32) << Instruction::ADD; m_context << Instruction::DUP2 << u256(32) << Instruction::ADD;
utils().zeroInitialiseMemoryArray(arrayType); utils().zeroInitialiseMemoryArray(arrayType);
m_context << Instruction::POP;
} }
else m_context << skipInit;
m_context << Instruction::POP; m_context << Instruction::POP;
break; break;
} }
default: default:

View File

@ -6837,6 +6837,20 @@ BOOST_AUTO_TEST_CASE(skip_dynamic_types_for_structs)
BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(2), u256(6))); BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(2), u256(6)));
} }
BOOST_AUTO_TEST_CASE(create_dynamic_array_with_zero_length)
{
char const* sourceCode = R"(
contract C {
function f() returns (uint) {
var a = new uint[][](0);
return 7;
}
}
)";
compileAndRun(sourceCode, 0, "C");
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7)));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }