Clarify C++ evaluation order.

This commit is contained in:
chriseth 2021-09-08 12:18:00 +02:00
parent 4b0cd6cc8c
commit 0b5671c885

View File

@ -798,10 +798,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 = string args = expressionAsType(_binOp.leftExpression(), *commonType, true);
expressionAsType(_binOp.leftExpression(), *commonType, true) + args += ", " + expressionAsType(_binOp.rightExpression(), *commonType, true);
", " +
expressionAsType(_binOp.rightExpression(), *commonType, true);
string expr; string expr;
if (op == Token::Equal) if (op == Token::Equal)
@ -1115,16 +1113,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
IRVariable array = convert(*arguments[0], *TypeProvider::bytesMemory()); IRVariable array = convert(*arguments[0], *TypeProvider::bytesMemory());
IRVariable hashVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(32)); IRVariable hashVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(32));
string dataAreaFunction = m_utils.arrayDataAreaFunction(*TypeProvider::bytesMemory());
string arrayLengthFunction = m_utils.arrayLengthFunction(*TypeProvider::bytesMemory());
define(hashVariable) << define(hashVariable) <<
"keccak256(" << "keccak256(" <<
m_utils.arrayDataAreaFunction(*TypeProvider::bytesMemory()) << (dataAreaFunction + "(" + array.commaSeparatedList() + ")") <<
"(" << ", " <<
array.commaSeparatedList() << (arrayLengthFunction + "(" + array.commaSeparatedList() +")") <<
"), " << ")\n";
m_utils.arrayLengthFunction(*TypeProvider::bytesMemory()) <<
"(" <<
array.commaSeparatedList() <<
"))\n";
IRVariable selectorVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(4)); IRVariable selectorVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(4));
define(selectorVariable, hashVariable); define(selectorVariable, hashVariable);
selector = selectorVariable.name(); selector = selectorVariable.name();
@ -1249,16 +1245,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
{ {
auto array = convert(*arguments[0], *arrayType); auto array = convert(*arguments[0], *arrayType);
string dataAreaFunction = m_utils.arrayDataAreaFunction(*arrayType);
string arrayLengthFunction = m_utils.arrayLengthFunction(*arrayType);
define(_functionCall) << define(_functionCall) <<
"keccak256(" << "keccak256(" <<
m_utils.arrayDataAreaFunction(*arrayType) << (dataAreaFunction + "(" + array.commaSeparatedList() + ")") <<
"(" << ", " <<
array.commaSeparatedList() << (arrayLengthFunction + "(" + array.commaSeparatedList() +")") <<
"), " << ")\n";
m_utils.arrayLengthFunction(*arrayType) <<
"(" <<
array.commaSeparatedList() <<
"))\n";
} }
break; break;
} }
@ -1646,11 +1640,14 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) << expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
")\n"; ")\n";
else if (member == "code") else if (member == "code")
{
string externalCodeFunction = m_utils.externalCodeFunction();
define(_memberAccess) << define(_memberAccess) <<
m_utils.externalCodeFunction() << externalCodeFunction <<
"(" << "(" <<
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) << expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
")\n"; ")\n";
}
else if (member == "codehash") else if (member == "codehash")
define(_memberAccess) << define(_memberAccess) <<
"extcodehash(" << "extcodehash(" <<
@ -1946,7 +1943,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
assignInternalFunctionIDIfNotCalledDirectly(_memberAccess, resolvedFunctionDef); assignInternalFunctionIDIfNotCalledDirectly(_memberAccess, resolvedFunctionDef);
} }
else if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration)) else if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
handleVariableReference(*variable, _memberAccess); handleVariableReference(*variable, _memberAccess);
else if (memberFunctionType) else if (memberFunctionType)
{ {
switch (memberFunctionType->kind()) switch (memberFunctionType->kind())
@ -2149,8 +2146,9 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
} }
case DataLocation::CallData: case DataLocation::CallData:
{ {
string indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType);
string const indexAccessFunctionCall = string const indexAccessFunctionCall =
m_utils.calldataArrayIndexAccessFunction(arrayType) + indexAccessFunction +
"(" + "(" +
IRVariable(_indexAccess.baseExpression()).commaSeparatedList() + IRVariable(_indexAccess.baseExpression()).commaSeparatedList() +
", " + ", " +
@ -2867,13 +2865,16 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable
")\n"; ")\n";
} }
else if (auto const* literalType = dynamic_cast<StringLiteralType const*>(&_value.type())) else if (auto const* literalType = dynamic_cast<StringLiteralType const*>(&_value.type()))
{
string writeUInt = m_utils.writeToMemoryFunction(*TypeProvider::uint256());
appendCode() << appendCode() <<
m_utils.writeToMemoryFunction(*TypeProvider::uint256()) << writeUInt <<
"(" << "(" <<
_memory.address << _memory.address <<
", " << ", " <<
m_utils.copyLiteralToMemoryFunction(literalType->value()) + "()" << m_utils.copyLiteralToMemoryFunction(literalType->value()) + "()" <<
")\n"; ")\n";
}
else else
{ {
solAssert(_lvalue.type.sizeOnStack() == 1, ""); solAssert(_lvalue.type.sizeOnStack() == 1, "");
@ -2949,11 +2950,14 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)
solUnimplementedAssert(_lvalue.type.sizeOnStack() == 1, ""); solUnimplementedAssert(_lvalue.type.sizeOnStack() == 1, "");
solAssert(_lvalue.type == *_immutable.variable->type(), ""); solAssert(_lvalue.type == *_immutable.variable->type(), "");
if (m_context.executionContext() == IRGenerationContext::ExecutionContext::Creation) if (m_context.executionContext() == IRGenerationContext::ExecutionContext::Creation)
{
string readFunction = m_utils.readFromMemory(*_immutable.variable->type());
define(result) << define(result) <<
m_utils.readFromMemory(*_immutable.variable->type()) << readFunction <<
"(" << "(" <<
to_string(m_context.immutableMemoryOffset(*_immutable.variable)) << to_string(m_context.immutableMemoryOffset(*_immutable.variable)) <<
")\n"; ")\n";
}
else else
define(result) << "loadimmutable(\"" << to_string(_immutable.variable->id()) << "\")\n"; define(result) << "loadimmutable(\"" << to_string(_immutable.variable->id()) << "\")\n";
}, },