aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/ExpressionCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/codegen/ExpressionCompiler.cpp')
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 41cfcb69..5192ffa6 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -220,6 +220,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
rightIntermediateType = _assignment.rightHandSide().annotation().type->closestTemporaryType(
_assignment.leftHandSide().annotation().type
);
+ solAssert(rightIntermediateType, "");
utils().convertType(*_assignment.rightHandSide().annotation().type, *rightIntermediateType, cleanupNeeded);
_assignment.leftHandSide().accept(*this);
@@ -395,6 +396,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
TypePointer leftTargetType = commonType;
TypePointer rightTargetType = Token::isShiftOp(c_op) ? rightExpression.annotation().type->mobileType() : commonType;
+ solAssert(rightTargetType, "");
// for commutative operators, push the literal as late as possible to allow improved optimization
auto isLiteral = [](Expression const& _e)
@@ -616,6 +618,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
arguments.front()->accept(*this);
break;
case Location::Send:
+ case Location::Transfer:
_functionCall.expression().accept(*this);
// Provide the gas stipend manually at first because we may send zero ether.
// Will be zeroed if we send more than zero ether.
@@ -644,6 +647,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
),
{}
);
+ if (function.location() == Location::Transfer)
+ {
+ // Check if zero (out of stack or not enough balance).
+ m_context << Instruction::ISZERO;
+ m_context.appendConditionalInvalid();
+ }
break;
case Location::Selfdestruct:
arguments.front()->accept(*this);
@@ -808,6 +817,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
arguments[0]->accept(*this);
// stack: newLength storageSlot slotOffset argValue
TypePointer type = arguments[0]->annotation().type->closestTemporaryType(arrayType->baseType());
+ solAssert(type, "");
utils().convertType(*arguments[0]->annotation().type, *type);
utils().moveToStackTop(1 + type->sizeOnStack());
utils().moveToStackTop(1 + type->sizeOnStack());
@@ -959,6 +969,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
case FunctionType::Location::Bare:
case FunctionType::Location::BareCallCode:
case FunctionType::Location::BareDelegateCall:
+ case FunctionType::Location::Transfer:
_memberAccess.expression().accept(*this);
m_context << funType->externalIdentifier();
break;
@@ -1040,7 +1051,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
);
m_context << Instruction::BALANCE;
}
- else if ((set<string>{"send", "call", "callcode", "delegatecall"}).count(member))
+ else if ((set<string>{"send", "transfer", "call", "callcode", "delegatecall"}).count(member))
utils().convertType(
*_memberAccess.expression().annotation().type,
IntegerType(0, IntegerType::Modifier::Address),