aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CompilerUtils.cpp9
-rw-r--r--ExpressionCompiler.cpp23
-rw-r--r--Types.h3
3 files changed, 20 insertions, 15 deletions
diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp
index 349877a2..d4e705a3 100644
--- a/CompilerUtils.cpp
+++ b/CompilerUtils.cpp
@@ -274,10 +274,13 @@ void CompilerUtils::encodeToMemory(
else
{
copyToStackTop(argSize - stackPos + dynPointers + 2, _givenTypes[i]->getSizeOnStack());
- if (targetType->isValueType())
- convertType(*_givenTypes[i], *targetType, true);
solAssert(!!targetType, "Externalable type expected.");
- storeInMemoryDynamic(*targetType, _padToWordBoundaries);
+ TypePointer type = targetType;
+ if (_givenTypes[i]->isInStorage())
+ type = _givenTypes[i]; // delay conversion
+ else
+ convertType(*_givenTypes[i], *targetType, true);
+ storeInMemoryDynamic(*type, _padToWordBoundaries);
}
stackPos += _givenTypes[i]->getSizeOnStack();
}
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 12274c7a..c98d76f3 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -146,10 +146,13 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
{
CompilerContext::LocationSetter locationSetter(m_context, _assignment);
_assignment.getRightHandSide().accept(*this);
- if (_assignment.getType()->isValueType())
- utils().convertType(*_assignment.getRightHandSide().getType(), *_assignment.getType());
- // We need this conversion mostly in the case of compound assignments. For non-value types
- // the conversion is done in LValue::storeValue.
+ TypePointer type = _assignment.getRightHandSide().getType();
+ if (!_assignment.getType()->isInStorage())
+ {
+ utils().convertType(*type, *_assignment.getType());
+ type = _assignment.getType();
+ }
+
_assignment.getLeftHandSide().accept(*this);
solAssert(!!m_currentLValue, "LValue not retrieved.");
@@ -175,7 +178,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
}
}
- m_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
+ m_currentLValue->storeValue(*type, _assignment.getLocation());
m_currentLValue.reset();
return false;
}
@@ -1119,14 +1122,10 @@ void ExpressionCompiler::appendExternalFunctionCall(
void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression)
{
+ solAssert(_expectedType.isValueType(), "Not implemented for non-value types.");
_expression.accept(*this);
- if (_expectedType.isValueType())
- {
- utils().convertType(*_expression.getType(), _expectedType, true);
- utils().storeInMemoryDynamic(_expectedType);
- }
- else
- utils().storeInMemoryDynamic(*_expression.getType()->mobileType());
+ utils().convertType(*_expression.getType(), _expectedType, true);
+ utils().storeInMemoryDynamic(_expectedType);
}
void ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression)
diff --git a/Types.h b/Types.h
index 0f86ac95..70f7807c 100644
--- a/Types.h
+++ b/Types.h
@@ -202,6 +202,8 @@ public:
/// This returns the corresponding integer type for IntegerConstantTypes and the pointer type
/// for storage reference types.
virtual TypePointer mobileType() const { return shared_from_this(); }
+ /// @returns true if this type is a storage pointer or reference.
+ virtual bool isInStorage() const { return false; }
/// Returns the list of all members of this type. Default implementation: no members.
virtual MemberList const& getMembers() const { return EmptyMemberList; }
@@ -374,6 +376,7 @@ public:
virtual TypePointer copyForLocation(Location _location, bool _isPointer) const = 0;
virtual TypePointer mobileType() const override { return copyForLocation(m_location, true); }
+ virtual bool isInStorage() const override { return m_location == Location::Storage; }
/// Storage references can be pointers or bound references. In general, local variables are of
/// pointer type, state variables are bound references. Assignments to pointers or deleting