From 56425bb2b1cb9937b7c7a6baaee5ddcdd1f2e3d1 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 17 Oct 2018 22:07:05 +0200 Subject: [PATCH 1/2] Add a test for delete x.length --- test/libsolidity/SolidityEndToEndTest.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 7a496e643..7f865aa11 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1787,6 +1787,24 @@ BOOST_AUTO_TEST_CASE(deleteLocals) ABI_CHECK(callContractFunction("delLocal()"), encodeArgs(6, 7)); } +BOOST_AUTO_TEST_CASE(deleteLength) +{ + char const* sourceCode = R"( + contract test { + uint[] x; + function f() public returns (uint){ + x.length = 1; + x[0] = 1; + delete x.length; + return x.length; + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(0)); + BOOST_CHECK(storageEmpty(m_contractAddress)); +} + BOOST_AUTO_TEST_CASE(constructor) { char const* sourceCode = R"( From c14dfeb8c5ffcc15cff1014a39ffa425aee1430a Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 17 Oct 2018 22:17:33 +0200 Subject: [PATCH 2/2] Removed unreachable cases in LValue.cpp. --- libsolidity/codegen/LValue.cpp | 49 +++++----------------------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 776846832..790ab309e 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -134,8 +134,7 @@ void MemoryItem::storeValue(Type const& _sourceType, SourceLocation const&, bool void MemoryItem::setToZero(SourceLocation const&, bool _removeReference) const { CompilerUtils utils(m_context); - if (!_removeReference) - m_context << Instruction::DUP1; + solAssert(_removeReference, ""); utils.pushZeroValue(*m_dataType); utils.storeInMemoryDynamic(*m_dataType, m_padded); m_context << Instruction::POP; @@ -460,8 +459,7 @@ void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, boo void StorageByteArrayElement::setToZero(SourceLocation const&, bool _removeReference) const { // stack: ref byte_number - if (!_removeReference) - m_context << Instruction::DUP2 << Instruction::DUP2; + solAssert(_removeReference, ""); m_context << u256(31) << Instruction::SUB << u256(0x100) << Instruction::EXP; // stack: ref (1<<(8*(31-byte_number))) m_context << Instruction::DUP2 << Instruction::SLOAD; @@ -498,8 +496,7 @@ void StorageArrayLength::storeValue(Type const&, SourceLocation const&, bool _mo void StorageArrayLength::setToZero(SourceLocation const&, bool _removeReference) const { - if (!_removeReference) - m_context << Instruction::DUP1; + solAssert(_removeReference, ""); ArrayUtils(m_context).clearDynamicArray(m_arrayType); } @@ -521,24 +518,9 @@ unsigned TupleObject::sizeOnStack() const return size; } -void TupleObject::retrieveValue(SourceLocation const& _location, bool _remove) const +void TupleObject::retrieveValue(SourceLocation const&, bool) const { - unsigned initialDepth = sizeOnStack(); - unsigned initialStack = m_context.stackHeight(); - for (auto const& lv: m_lvalues) - if (lv) - { - solAssert(initialDepth + m_context.stackHeight() >= initialStack, ""); - unsigned depth = initialDepth + m_context.stackHeight() - initialStack; - if (lv->sizeOnStack() > 0) - { - if (_remove && depth > lv->sizeOnStack()) - CompilerUtils(m_context).moveToStackTop(depth, depth - lv->sizeOnStack()); - else if (!_remove && depth > 0) - CompilerUtils(m_context).copyToStackTop(depth, lv->sizeOnStack()); - } - lv->retrieveValue(_location, true); - } + solAssert(false, "Tried to retrieve value of tuple."); } void TupleObject::storeValue(Type const& _sourceType, SourceLocation const& _location, bool) const @@ -569,24 +551,7 @@ void TupleObject::storeValue(Type const& _sourceType, SourceLocation const& _loc CompilerUtils(m_context).popStackElement(_sourceType); } -void TupleObject::setToZero(SourceLocation const& _location, bool _removeReference) const +void TupleObject::setToZero(SourceLocation const&, bool) const { - if (_removeReference) - { - for (size_t i = 0; i < m_lvalues.size(); ++i) - if (m_lvalues[m_lvalues.size() - i]) - m_lvalues[m_lvalues.size() - i]->setToZero(_location, true); - } - else - { - unsigned depth = sizeOnStack(); - for (auto const& val: m_lvalues) - if (val) - { - if (val->sizeOnStack() > 0) - CompilerUtils(m_context).copyToStackTop(depth, val->sizeOnStack()); - val->setToZero(_location, false); - depth -= val->sizeOnStack(); - } - } + solAssert(false, "Tried to delete tuple."); }