aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/LValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/codegen/LValue.cpp')
-rw-r--r--libsolidity/codegen/LValue.cpp19
1 files changed, 13 insertions, 6 deletions
diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp
index 3f1730d1..23fe2d4e 100644
--- a/libsolidity/codegen/LValue.cpp
+++ b/libsolidity/codegen/LValue.cpp
@@ -216,11 +216,14 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _location, bool _move) const
{
CompilerUtils utils(m_context);
+ solAssert(m_dataType, "");
+
// stack: value storage_key storage_offset
if (m_dataType->isValueType())
{
solAssert(m_dataType->storageBytes() <= 32, "Invalid storage bytes size.");
solAssert(m_dataType->storageBytes() > 0, "Invalid storage bytes size.");
+
if (m_dataType->storageBytes() == 32)
{
solAssert(m_dataType->sizeOnStack() == 1, "Invalid stack size.");
@@ -228,6 +231,11 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
m_context << Instruction::POP;
if (!_move)
m_context << Instruction::DUP2 << Instruction::SWAP1;
+
+ m_context << Instruction::SWAP1;
+ utils.convertType(_sourceType, *m_dataType, true);
+ m_context << Instruction::SWAP1;
+
m_context << Instruction::SSTORE;
}
else
@@ -248,6 +256,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
// stack: value storage_ref cleared_value multiplier value
if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType))
{
+ solAssert(_sourceType == *m_dataType, "function item stored but target is not equal to source");
if (fun->location() == FunctionType::Location::External)
// Combine the two-item function type into a single stack slot.
utils.combineExternalFunctionType(false);
@@ -257,19 +266,17 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
Instruction::AND;
}
else if (m_dataType->category() == Type::Category::FixedBytes)
+ {
+ solAssert(_sourceType.category() == Type::Category::FixedBytes, "source not fixed bytes");
m_context
<< (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes()))
<< Instruction::SWAP1 << Instruction::DIV;
+ }
else
{
solAssert(m_dataType->sizeOnStack() == 1, "Invalid stack size for opaque type.");
// remove the higher order bits
- m_context
- << (u256(1) << (8 * (32 - m_dataType->storageBytes())))
- << Instruction::SWAP1
- << Instruction::DUP2
- << Instruction::MUL
- << Instruction::DIV;
+ utils.convertType(_sourceType, *m_dataType, true, true);
}
m_context << Instruction::MUL << Instruction::OR;
// stack: value storage_ref updated_value