diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index d68bc39c6..86d00dbc9 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -805,8 +805,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) if (auto type = dynamic_cast(commonType)) isSigned = type->isSigned(); - string args = expressionAsType(_binOp.leftExpression(), *commonType, true); - args += ", " + expressionAsType(_binOp.rightExpression(), *commonType, true); + string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType); + args += ", " + expressionAsCleanedType(_binOp.rightExpression(), *commonType); auto functionType = dynamic_cast(commonType); solAssert(functionType ? (op == Token::Equal || op == Token::NotEqual) : true, "Invalid function pointer comparison!"); @@ -1037,7 +1037,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) else { solAssert(parameterTypes[i]->sizeOnStack() == 1, ""); - indexedArgs.emplace_back(convert(arg, *paramTypes[i], true)); + indexedArgs.emplace_back(convertAndCleanup(arg, *parameterTypes[i])); } } else @@ -2727,32 +2727,43 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly( m_context.addToInternalDispatch(_referencedFunction); } -IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to, bool _forceCleanup) +IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to) { - if (_from.type() == _to && !_forceCleanup) + if (_from.type() == _to) return _from; else { IRVariable converted(m_context.newYulVariable(), _to); - define(converted, _from, _forceCleanup); + define(converted, _from); return converted; } } -std::string IRGeneratorForStatements::expressionAsType(Expression const& _expression, Type const& _to, bool _forceCleanup) +IRVariable IRGeneratorForStatements::convertAndCleanup(IRVariable const& _from, Type const& _to) +{ + IRVariable converted(m_context.newYulVariable(), _to); + defineAndCleanup(converted, _from); + return converted; +} + +std::string IRGeneratorForStatements::expressionAsType(Expression const& _expression, Type const& _to) { IRVariable from(_expression); if (from.type() == _to) - { - if (_forceCleanup) - return m_utils.cleanupFunction(_to) + "(" + from.commaSeparatedList() + ")"; - else - return from.commaSeparatedList(); - } + return from.commaSeparatedList(); else return m_utils.conversionFunction(from.type(), _to) + "(" + from.commaSeparatedList() + ")"; } +std::string IRGeneratorForStatements::expressionAsCleanedType(Expression const& _expression, Type const& _to) +{ + IRVariable from(_expression); + if (from.type() == _to) + return m_utils.cleanupFunction(_to) + "(" + expressionAsType(_expression, _to) + ")"; + else + return expressionAsType(_expression, _to) ; +} + std::ostream& IRGeneratorForStatements::define(IRVariable const& _var) { if (_var.type().sizeOnStack() > 0) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 10e8f0b5e..11f8b3c84 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -86,10 +86,19 @@ public: IRVariable evaluateExpression(Expression const& _expression, Type const& _to); /// Defines @a _var using the value of @a _value while performing type conversions, if required. - /// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion. - void define(IRVariable const& _var, IRVariable const& _value, bool _forceCleanup = false) + void define(IRVariable const& _var, IRVariable const& _value) { - declareAssign(_var, _value, true, _forceCleanup); + bool _declare = true; + declareAssign(_var, _value, _declare); + } + + /// Defines @a _var using the value of @a _value while performing type conversions, if required. + /// It also cleans the value of the variable. + void defineAndCleanup(IRVariable const& _var, IRVariable const& _value) + { + bool _forceCleanup = true; + bool _declare = true; + declareAssign(_var, _value, _declare, _forceCleanup); } /// @returns the name of a function that computes the value of the given constant @@ -166,13 +175,20 @@ private: ); /// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable - /// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion. - IRVariable convert(IRVariable const& _variable, Type const& _to, bool _forceCleanup = false); + IRVariable convert(IRVariable const& _variable, Type const& _to); + + /// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable + /// It also cleans the value of the variable. + IRVariable convertAndCleanup(IRVariable const& _from, Type const& _to); /// @returns a Yul expression representing the current value of @a _expression, /// converted to type @a _to if it does not yet have that type. - /// If @a _forceCleanup is set to true, it also cleans the value, in case it already has type @a _to. - std::string expressionAsType(Expression const& _expression, Type const& _to, bool _forceCleanup = false); + std::string expressionAsType(Expression const& _expression, Type const& _to); + + /// @returns a Yul expression representing the current value of @a _expression, + /// converted to type @a _to if it does not yet have that type. + /// It also cleans the value, in case it already has type @a _to. + std::string expressionAsCleanedType(Expression const& _expression, Type const& _to); /// @returns an output stream that can be used to define @a _var using a function call or /// single stack slot expression.