diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index bd86dc9c2..cd47d417a 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3258,6 +3258,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) switch (fromCategory) { case Type::Category::Address: + case Type::Category::Contract: body = Whiskers("converted := (value)") ("convert", conversionFunction(IntegerType(160), _to)) @@ -3265,61 +3266,44 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) break; case Type::Category::Integer: case Type::Category::RationalNumber: - case Type::Category::Contract: { + solAssert(_from.mobileType(), ""); if (RationalNumberType const* rational = dynamic_cast(&_from)) - solUnimplementedAssert(!rational->isFractional(), "Not yet implemented - FixedPointType."); + if (rational->isFractional()) + solAssert(toCategory == Type::Category::FixedPoint, ""); + if (toCategory == Type::Category::FixedBytes) { - solAssert( - fromCategory == Type::Category::Integer || fromCategory == Type::Category::RationalNumber, - "Invalid conversion to FixedBytesType requested." - ); FixedBytesType const& toBytesType = dynamic_cast(_to); body = Whiskers("converted := ((value))") - ("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8)) - ("clean", cleanupFunction(_from)) - .render(); + ("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8)) + ("clean", cleanupFunction(_from)) + .render(); } else if (toCategory == Type::Category::Enum) - { - solAssert(_from.mobileType(), ""); body = Whiskers("converted := ((value))") ("cleanEnum", cleanupFunction(_to)) - // "mobileType()" returns integer type for rational - ("cleanInt", cleanupFunction(*_from.mobileType())) + ("cleanInt", cleanupFunction(_from)) .render(); - } else if (toCategory == Type::Category::FixedPoint) solUnimplemented("Not yet implemented - FixedPointType."); - else if (toCategory == Type::Category::Address) + else if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract) body = Whiskers("converted := (value)") - ("convert", conversionFunction(_from, IntegerType(160))) - .render(); - else + ("convert", conversionFunction(_from, IntegerType(160))) + .render(); + else if (toCategory == Type::Category::Integer) { - solAssert( - toCategory == Type::Category::Integer || - toCategory == Type::Category::Contract, - ""); - IntegerType const addressType(160); - IntegerType const& to = - toCategory == Type::Category::Integer ? - dynamic_cast(_to) : - addressType; + IntegerType const& to = dynamic_cast(_to); // Clean according to the "to" type, except if this is // a widening conversion. IntegerType const* cleanupType = &to; - if (fromCategory != Type::Category::RationalNumber) + if (fromCategory == Type::Category::Integer) { - IntegerType const& from = - fromCategory == Type::Category::Integer ? - dynamic_cast(_from) : - addressType; + IntegerType const& from = dynamic_cast(_from); if (to.numBits() > from.numBits()) cleanupType = &from; } @@ -3328,6 +3312,8 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) ("cleanInt", cleanupFunction(*cleanupType)) .render(); } + else + solAssert(false, ""); break; } case Type::Category::Bool: diff --git a/test/cmdlineTests/yul_source_locations/output.json b/test/cmdlineTests/yul_source_locations/output.json index f5f57a6d6..ae7d70556 100644 --- a/test/cmdlineTests/yul_source_locations/output.json +++ b/test/cmdlineTests/yul_source_locations/output.json @@ -275,11 +275,7 @@ object \"C_54\" { } function convert_t_contract$_C_$54_to_t_address(value) -> converted { - converted := convert_t_contract$_C_$54_to_t_uint160(value) - } - - function convert_t_contract$_C_$54_to_t_uint160(value) -> converted { - converted := cleanup_t_uint160(value) + converted := convert_t_uint160_to_t_address(value) } function convert_t_int256_to_t_int256(value) -> converted { @@ -290,6 +286,14 @@ object \"C_54\" { converted := cleanup_t_int256(value) } + function convert_t_uint160_to_t_address(value) -> converted { + converted := convert_t_uint160_to_t_uint160(value) + } + + function convert_t_uint160_to_t_uint160(value) -> converted { + converted := cleanup_t_uint160(value) + } + function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value { value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value)) } @@ -875,11 +879,7 @@ object \"D_72\" { } function convert_t_contract$_C_$54_to_t_address(value) -> converted { - converted := convert_t_contract$_C_$54_to_t_uint160(value) - } - - function convert_t_contract$_C_$54_to_t_uint160(value) -> converted { - converted := cleanup_t_uint160(value) + converted := convert_t_uint160_to_t_address(value) } function convert_t_int256_to_t_int256(value) -> converted { @@ -890,6 +890,14 @@ object \"D_72\" { converted := cleanup_t_int256(value) } + function convert_t_uint160_to_t_address(value) -> converted { + converted := convert_t_uint160_to_t_uint160(value) + } + + function convert_t_uint160_to_t_uint160(value) -> converted { + converted := cleanup_t_uint160(value) + } + function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value { value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value)) } diff --git a/test/libsolidity/semanticTests/various/external_types_in_calls.sol b/test/libsolidity/semanticTests/various/external_types_in_calls.sol index 941a06a91..4aee63b93 100644 --- a/test/libsolidity/semanticTests/various/external_types_in_calls.sol +++ b/test/libsolidity/semanticTests/various/external_types_in_calls.sol @@ -27,5 +27,5 @@ contract C { // compileViaYul: also // ---- // test() -> 9, 7 -// gas legacy: 121594 +// gas legacy: 125064 // t2() -> 9