diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index bb68a663f..38efb2a73 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -311,8 +311,6 @@ void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove) void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const { - //@todo optimize this - // stack: value ref byte_number m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP; // stack: value ref (1<<(8*(31-byte_number))) @@ -335,19 +333,16 @@ void StorageByteArrayElement::setToZero(SourceLocation const&, bool _removeRefer { // stack: ref byte_number if (!_removeReference) - m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; + m_context << eth::Instruction::DUP2 << eth::Instruction::DUP2; m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP; // stack: ref (1<<(8*(31-byte_number))) m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD; // stack: ref (1<<(8*(31-byte_number))) old_full_value // clear byte in old value - m_context << eth::Instruction::SWAP1 << u256(0xff) << eth::Instruction::MUL << eth::Instruction::AND; + m_context << eth::Instruction::SWAP1 << u256(0xff) << eth::Instruction::MUL; + m_context << eth::Instruction::NOT << eth::Instruction::AND; // stack: ref old_full_value_with_cleared_byte m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE; - if (!_removeReference) - m_context << eth::Instruction::SWAP1; - else - m_context << eth::Instruction::POP; } StorageArrayLength::StorageArrayLength(CompilerContext& _compilerContext, const ArrayType& _arrayType): diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 596f710b9..24e5f7b4e 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -3381,6 +3381,26 @@ BOOST_AUTO_TEST_CASE(bytes_index_access) BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193)); } +BOOST_AUTO_TEST_CASE(bytes_delete_element) +{ + char const* sourceCode = R"( + contract c { + bytes data; + function test1() external returns (bool) { + data.length = 100; + for (uint i = 0; i < data.length; i++) + data[i] = byte(i); + delete data[94]; + delete data[96]; + delete data[98]; + return data[94] == 0 && data[95] == 95 && data[96] == 0 && data[97] == 97; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test1()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_CASE(array_copy_calldata_storage) { char const* sourceCode = R"(