mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
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:
commit
f4e0270374
@ -805,8 +805,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
|
|||||||
if (auto type = dynamic_cast<IntegerType const*>(commonType))
|
if (auto type = dynamic_cast<IntegerType const*>(commonType))
|
||||||
isSigned = type->isSigned();
|
isSigned = type->isSigned();
|
||||||
|
|
||||||
string args = expressionAsType(_binOp.leftExpression(), *commonType, true);
|
string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType);
|
||||||
args += ", " + expressionAsType(_binOp.rightExpression(), *commonType, true);
|
args += ", " + expressionAsCleanedType(_binOp.rightExpression(), *commonType);
|
||||||
|
|
||||||
auto functionType = dynamic_cast<FunctionType const*>(commonType);
|
auto functionType = dynamic_cast<FunctionType const*>(commonType);
|
||||||
solAssert(functionType ? (op == Token::Equal || op == Token::NotEqual) : true, "Invalid function pointer comparison!");
|
solAssert(functionType ? (op == Token::Equal || op == Token::NotEqual) : true, "Invalid function pointer comparison!");
|
||||||
@ -1037,7 +1037,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
solAssert(parameterTypes[i]->sizeOnStack() == 1, "");
|
solAssert(parameterTypes[i]->sizeOnStack() == 1, "");
|
||||||
indexedArgs.emplace_back(convert(arg, *paramTypes[i], true));
|
indexedArgs.emplace_back(convertAndCleanup(arg, *parameterTypes[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2727,32 +2727,43 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly(
|
|||||||
m_context.addToInternalDispatch(_referencedFunction);
|
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;
|
return _from;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IRVariable converted(m_context.newYulVariable(), _to);
|
IRVariable converted(m_context.newYulVariable(), _to);
|
||||||
define(converted, _from, _forceCleanup);
|
define(converted, _from);
|
||||||
return converted;
|
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);
|
IRVariable from(_expression);
|
||||||
if (from.type() == _to)
|
if (from.type() == _to)
|
||||||
{
|
return from.commaSeparatedList();
|
||||||
if (_forceCleanup)
|
|
||||||
return m_utils.cleanupFunction(_to) + "(" + from.commaSeparatedList() + ")";
|
|
||||||
else
|
|
||||||
return from.commaSeparatedList();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return m_utils.conversionFunction(from.type(), _to) + "(" + from.commaSeparatedList() + ")";
|
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)
|
std::ostream& IRGeneratorForStatements::define(IRVariable const& _var)
|
||||||
{
|
{
|
||||||
if (_var.type().sizeOnStack() > 0)
|
if (_var.type().sizeOnStack() > 0)
|
||||||
|
@ -86,10 +86,19 @@ public:
|
|||||||
IRVariable evaluateExpression(Expression const& _expression, Type const& _to);
|
IRVariable evaluateExpression(Expression const& _expression, Type const& _to);
|
||||||
|
|
||||||
/// Defines @a _var using the value of @a _value while performing type conversions, if required.
|
/// 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)
|
||||||
void define(IRVariable const& _var, IRVariable const& _value, bool _forceCleanup = false)
|
|
||||||
{
|
{
|
||||||
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
|
/// @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
|
/// 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);
|
||||||
IRVariable convert(IRVariable const& _variable, Type const& _to, bool _forceCleanup = false);
|
|
||||||
|
/// 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,
|
/// @returns a Yul expression representing the current value of @a _expression,
|
||||||
/// converted to type @a _to if it does not yet have that type.
|
/// 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);
|
||||||
std::string expressionAsType(Expression const& _expression, Type const& _to, bool _forceCleanup = false);
|
|
||||||
|
/// @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
|
/// @returns an output stream that can be used to define @a _var using a function call or
|
||||||
/// single stack slot expression.
|
/// single stack slot expression.
|
||||||
|
Loading…
Reference in New Issue
Block a user