@@ -705,8 +705,8 @@ void SMTChecker::visitGasLeft(FunctionCall const& _funCall)
705
705
706
706
void SMTChecker::inlineFunctionCall (FunctionCall const & _funCall)
707
707
{
708
- FunctionDefinition const * _funDef = inlinedFunctionCallToDefinition (_funCall);
709
- if (!_funDef )
708
+ FunctionDefinition const * funDef = inlinedFunctionCallToDefinition (_funCall);
709
+ if (!funDef )
710
710
{
711
711
m_errorReporter.warning (
712
712
_funCall.location (),
@@ -715,39 +715,48 @@ void SMTChecker::inlineFunctionCall(FunctionCall const& _funCall)
715
715
return ;
716
716
}
717
717
718
- if (visitedFunction (_funDef ))
718
+ if (visitedFunction (funDef ))
719
719
m_errorReporter.warning (
720
720
_funCall.location (),
721
721
" Assertion checker does not support recursive function calls." ,
722
- SecondarySourceLocation ().append (" Starting from function:" , _funDef ->location ())
722
+ SecondarySourceLocation ().append (" Starting from function:" , funDef ->location ())
723
723
);
724
724
else
725
725
{
726
726
vector<smt::Expression> funArgs;
727
727
Expression const * calledExpr = &_funCall.expression ();
728
728
auto const & funType = dynamic_cast <FunctionType const *>(calledExpr->annotation ().type );
729
729
solAssert (funType, " " );
730
+
730
731
if (funType->bound ())
731
732
{
732
733
auto const & boundFunction = dynamic_cast <MemberAccess const *>(calledExpr);
733
734
solAssert (boundFunction, " " );
734
735
funArgs.push_back (expr (boundFunction->expression ()));
735
736
}
737
+
736
738
for (auto arg: _funCall.arguments ())
737
739
funArgs.push_back (expr (*arg));
738
- initializeFunctionCallParameters (*_funDef, funArgs);
739
- _funDef->accept (*this );
740
- auto const & returnParams = _funDef->returnParameters ();
741
- if (_funDef->returnParameters ().size ())
740
+ initializeFunctionCallParameters (*funDef, funArgs);
741
+
742
+ funDef->accept (*this );
743
+
744
+ createExpr (_funCall);
745
+ auto const & returnParams = funDef->returnParameters ();
746
+ if (returnParams.size () > 1 )
742
747
{
743
- if (returnParams.size () > 1 )
744
- m_errorReporter.warning (
745
- _funCall.location (),
746
- " Assertion checker does not yet support calls to functions that return more than one value."
747
- );
748
- else
749
- defineExpr (_funCall, currentValue (*returnParams[0 ]));
748
+ vector<shared_ptr<SymbolicVariable>> components;
749
+ for (auto param: returnParams)
750
+ {
751
+ solAssert (m_variables[param.get ()], " " );
752
+ components.push_back (m_variables[param.get ()]);
753
+ }
754
+ auto const & symbTuple = dynamic_pointer_cast<SymbolicTupleVariable>(m_expressions[&_funCall]);
755
+ solAssert (symbTuple, " " );
756
+ symbTuple->setComponents (move (components));
750
757
}
758
+ else if (returnParams.size () == 1 )
759
+ defineExpr (_funCall, currentValue (*returnParams.front ()));
751
760
}
752
761
}
753
762
@@ -829,15 +838,11 @@ void SMTChecker::visitTypeConversion(FunctionCall const& _funCall)
829
838
void SMTChecker::visitFunctionIdentifier (Identifier const & _identifier)
830
839
{
831
840
auto const & fType = dynamic_cast <FunctionType const &>(*_identifier.annotation ().type );
832
- if (fType .returnParameterTypes ().size () > 1 )
841
+ if (fType .returnParameterTypes ().size () == 1 )
833
842
{
834
- m_errorReporter.warning (
835
- _identifier.location (),
836
- " Assertion checker does not yet support functions with more than one return parameter."
837
- );
843
+ defineGlobalFunction (fType .richIdentifier (), _identifier);
844
+ m_expressions.emplace (&_identifier, m_globalContext.at (fType .richIdentifier ()));
838
845
}
839
- defineGlobalFunction (fType .richIdentifier (), _identifier);
840
- m_expressions.emplace (&_identifier, m_globalContext.at (fType .richIdentifier ()));
841
846
}
842
847
843
848
void SMTChecker::endVisit (Literal const & _literal)
@@ -873,12 +878,17 @@ void SMTChecker::endVisit(Return const& _return)
873
878
{
874
879
auto returnParams = m_functionPath.back ()->returnParameters ();
875
880
if (returnParams.size () > 1 )
876
- m_errorReporter.warning (
877
- _return.location (),
878
- " Assertion checker does not yet support more than one return value."
879
- );
881
+ {
882
+ auto tuple = dynamic_cast <TupleExpression const *>(_return.expression ());
883
+ solAssert (tuple, " " );
884
+ auto const & components = tuple->components ();
885
+ solAssert (components.size () == returnParams.size (), " " );
886
+ for (unsigned i = 0 ; i < returnParams.size (); ++i)
887
+ if (components.at (i))
888
+ m_interface->addAssertion (expr (*components.at (i)) == newValue (*returnParams.at (i)));
889
+ }
880
890
else if (returnParams.size () == 1 )
881
- m_interface->addAssertion (expr (*_return.expression ()) == newValue (*returnParams[ 0 ] ));
891
+ m_interface->addAssertion (expr (*_return.expression ()) == newValue (*returnParams. front () ));
882
892
}
883
893
}
884
894
0 commit comments