diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 06e9367de..42d92fbd5 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -155,8 +155,31 @@ void IRGeneratorForStatements::endVisit(BinaryOperation const& _binOp) bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall) { - solUnimplementedAssert(_functionCall.annotation().kind == FunctionCallKind::FunctionCall, ""); - FunctionTypePointer functionType = dynamic_cast(_functionCall.expression().annotation().type); + solUnimplementedAssert( + _functionCall.annotation().kind == FunctionCallKind::FunctionCall || + _functionCall.annotation().kind == FunctionCallKind::TypeConversion, + "This type of function call is not yet implemented" + ); + + TypePointer const funcType = _functionCall.expression().annotation().type; + + if (_functionCall.annotation().kind == FunctionCallKind::TypeConversion) + { + solAssert(funcType->category() == Type::Category::TypeType, "Expected category to be TypeType"); + solAssert(_functionCall.arguments().size() == 1, "Expected one argument for type conversion"); + _functionCall.arguments().front()->accept(*this); + + m_code << + "let " << + m_context.variable(_functionCall) << + " := " << + expressionAsType(*_functionCall.arguments().front(), *_functionCall.annotation().type) << + "\n"; + + return false; + } + + FunctionTypePointer functionType = dynamic_cast(funcType); TypePointers parameterTypes = functionType->parameterTypes(); vector> const& callArguments = _functionCall.arguments(); diff --git a/test/libsolidity/semanticTests/viaYul/explicit_cast_assignment.sol b/test/libsolidity/semanticTests/viaYul/explicit_cast_assignment.sol new file mode 100644 index 000000000..6a9291c32 --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/explicit_cast_assignment.sol @@ -0,0 +1,10 @@ +contract C { + function f() public pure returns (uint16 x) { + uint8 y = uint8(0x12345678); + x = y; + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0x78 diff --git a/test/libsolidity/semanticTests/viaYul/explicit_cast_function_call.sol b/test/libsolidity/semanticTests/viaYul/explicit_cast_function_call.sol new file mode 100644 index 000000000..c239b07e4 --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/explicit_cast_function_call.sol @@ -0,0 +1,12 @@ +contract C { + function f(bytes32 b) public pure returns (bytes32 x) { + x = b; + } + function g() public pure returns (bytes32 x) { + x = f(bytes4(uint32(0x12345678))); + } +} +// ==== +// compileViaYul: true +// ---- +// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/viaYul/explicit_cast_local_assignment.sol b/test/libsolidity/semanticTests/viaYul/explicit_cast_local_assignment.sol new file mode 100644 index 000000000..22bb1f7ea --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/explicit_cast_local_assignment.sol @@ -0,0 +1,10 @@ +contract C { + function f(uint a) public pure returns (uint8 x) { + uint8 b = uint8(a); + x = b; + } +} +// ==== +// compileViaYul: true +// ---- +// f(uint256): 0x12345678 -> 0x78