Merge pull request #12605 from nishant-sachdeva/indexed_log_topic_differs_between_legacy_and_ir_if_explicitly_downcast

Code generators needed fixing of the cleanup process during typecasting of bytes and integers
This commit is contained in:
chriseth 2022-02-01 12:35:10 +01:00 committed by GitHub
commit f4e0270374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 20 deletions

View File

@ -805,8 +805,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
if (auto type = dynamic_cast<IntegerType const*>(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<FunctionType const*>(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();
}
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)

View File

@ -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.