aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/Compiler.cpp')
-rw-r--r--libsolidity/Compiler.cpp16
1 files changed, 12 insertions, 4 deletions
diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp
index 7c6c7831..679704ba 100644
--- a/libsolidity/Compiler.cpp
+++ b/libsolidity/Compiler.cpp
@@ -597,13 +597,20 @@ bool Compiler::visit(Break const& _breakStatement)
bool Compiler::visit(Return const& _return)
{
CompilerContext::LocationSetter locationSetter(m_context, _return);
- //@todo modifications are needed to make this work with functions returning multiple values
if (Expression const* expression = _return.expression())
{
solAssert(_return.annotation().functionReturnParameters, "Invalid return parameters pointer.");
- VariableDeclaration const& firstVariable = *_return.annotation().functionReturnParameters->parameters().front();
- compileExpression(*expression, firstVariable.annotation().type);
- CompilerUtils(m_context).moveToStackVariable(firstVariable);
+ vector<ASTPointer<VariableDeclaration>> const& returnParameters =
+ _return.annotation().functionReturnParameters->parameters();
+ TypePointers types;
+ for (auto const& retVariable: returnParameters)
+ types.push_back(retVariable->annotation().type);
+
+ TypePointer expectedType = types.size() == 1 ? types.front() : make_shared<TupleType>(types);
+ compileExpression(*expression, expectedType);
+
+ for (auto const& retVariable: boost::adaptors::reverse(returnParameters))
+ CompilerUtils(m_context).moveToStackVariable(*retVariable);
}
for (unsigned i = 0; i < m_stackCleanupForReturn; ++i)
m_context << eth::Instruction::POP;
@@ -637,6 +644,7 @@ bool Compiler::visit(VariableDeclarationStatement const& _variableDeclarationSta
for (size_t i = 0; i < assignments.size(); ++i)
{
size_t j = assignments.size() - i - 1;
+ solAssert(!!valueTypes[j], "");
VariableDeclaration const* varDecl = assignments[j];
if (!varDecl)
utils.popStackElement(*valueTypes[j]);