Browse Source

Delete for memory objects.

cl-refactor
chriseth 10 years ago
parent
commit
f95baf2cb9
  1. 22
      libsolidity/ExpressionCompiler.cpp
  2. 13
      libsolidity/LValue.cpp
  3. 29
      test/libsolidity/SolidityEndToEndTest.cpp
  4. 26
      test/libsolidity/SolidityNameAndTypeResolution.cpp

22
libsolidity/ExpressionCompiler.cpp

@ -679,10 +679,24 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
case Type::Category::Struct:
{
StructType const& type = dynamic_cast<StructType const&>(*_memberAccess.getExpression().getType());
m_context << eth::Instruction::POP; // structs always align to new slot
pair<u256, unsigned> const& offsets = type.getStorageOffsetsOfMember(member);
m_context << offsets.first << eth::Instruction::ADD << u256(offsets.second);
setLValueToStorageItem(_memberAccess);
switch (type.location())
{
case DataLocation::Storage:
{
m_context << eth::Instruction::POP; // structs always align to new slot
pair<u256, unsigned> const& offsets = type.getStorageOffsetsOfMember(member);
m_context << offsets.first << eth::Instruction::ADD << u256(offsets.second);
setLValueToStorageItem(_memberAccess);
break;
}
case DataLocation::Memory:
{
solAssert(false, "Member access for memory structs not yet implemented.");
break;
}
default:
solAssert(false, "Illegal data location for struct.");
}
break;
}
case Type::Category::Enum:

13
libsolidity/LValue.cpp

@ -69,17 +69,8 @@ void StackVariable::storeValue(Type const&, SourceLocation const& _location, boo
void StackVariable::setToZero(SourceLocation const& _location, bool) const
{
unsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset);
if (stackDiff > 16)
BOOST_THROW_EXCEPTION(
CompilerError() <<
errinfo_sourceLocation(_location) <<
errinfo_comment("Stack too deep, try removing local variables.")
);
solAssert(stackDiff >= m_size - 1, "");
for (unsigned i = 0; i < m_size; ++i)
m_context << u256(0) << eth::swapInstruction(stackDiff + 1 - i)
<< eth::Instruction::POP;
CompilerUtils(m_context).pushZeroValue(m_dataType);
storeValue(m_dataType, _location, true);
}
MemoryItem::MemoryItem(CompilerContext& _compilerContext, Type const& _type, bool _padded):

29
test/libsolidity/SolidityEndToEndTest.cpp

@ -4691,6 +4691,35 @@ BOOST_AUTO_TEST_CASE(memory_types_initialisation)
BOOST_CHECK(callContractFunction("nestedStat()") == encodeArgs(vector<u256>(3 * 7)));
}
BOOST_AUTO_TEST_CASE(memory_arrays_delete)
{
char const* sourceCode = R"(
contract Test {
function del() returns (uint24[3][4]) {
uint24[3][4] memory x;
for (uint24 i = 0; i < x.length; i ++)
for (uint24 j = 0; j < x[i].length; j ++)
x[i][j] = i * 0x10 + j;
delete x[1];
delete x[3][2];
return x;
}
}
)";
compileAndRun(sourceCode, 0, "Test");
vector<u256> data(3 * 4);
for (unsigned i = 0; i < 4; i++)
for (unsigned j = 0; j < 3; j++)
{
u256 v = 0;
if (!(i == 1 || (i == 3 && j == 2)))
v = i * 0x10 + j;
data[i * 3 + j] = v;
}
BOOST_CHECK(callContractFunction("del()") == encodeArgs(data));
}
BOOST_AUTO_TEST_CASE(memory_arrays_index_access_write)
{
char const* sourceCode = R"(

26
test/libsolidity/SolidityNameAndTypeResolution.cpp

@ -1900,6 +1900,18 @@ BOOST_AUTO_TEST_CASE(storage_location_local_variables)
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode));
}
BOOST_AUTO_TEST_CASE(no_mappings_in_memory_array)
{
char const* sourceCode = R"(
contract C {
function f() {
mapping(uint=>uint)[] memory x;
}
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
{
char const* sourceCode = R"(
@ -1931,6 +1943,20 @@ BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
{
char const* sourceCode = R"(
contract C {
uint[] data;
function f() {
var x = data;
delete x;
}
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(assignment_mem_storage_variable_directly)
{
char const* sourceCode = R"(

Loading…
Cancel
Save