diff --git a/libsolidity/codegen/ReturnInfo.cpp b/libsolidity/codegen/ReturnInfo.cpp
index fd2ff451f..28518d9b2 100644
--- a/libsolidity/codegen/ReturnInfo.cpp
+++ b/libsolidity/codegen/ReturnInfo.cpp
@@ -54,4 +54,6 @@ ReturnInfo::ReturnInfo(EVMVersion const& _evmVersion, FunctionType const& _funct
estimatedReturnSize += retType->decodingType()->calldataEncodedSize();
}
}
+ if (dynamicReturnSize)
+ solAssert(estimatedReturnSize == 0);
}
diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp
index 9fb73f021..ed49c94b0 100644
--- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp
+++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp
@@ -2505,6 +2505,8 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << to_string(returnInfo.estimatedReturnSize) << "), 0)\n";
}
+ // NOTE: When the expected size of returndata is static, we pass that in to the call opcode and it gets copied automatically.
+ // When it's dynamic, we get zero from estimatedReturnSize() instead and then we need an explicit returndatacopy().
Whiskers templ(R"(
if iszero(extcodesize(
)) { () }
@@ -2514,22 +2516,29 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
mstore(, ())
let := (add(, 4) )
- let := (, , , , sub(, ), , )
+ let := (, , , , sub(, ), , )
if iszero() { () }
+retVars> let +retVars>
if {
-
- // copy dynamic return data out
- returndatacopy(, 0, returndatasize())
-
+
+ let := returndatasize()
+ returndatacopy(, 0, )
+
+ let :=
+
+ if gt(, returndatasize()) {
+ := returndatasize()
+ }
+
+
// update freeMemoryPointer according to dynamic return size
- (, )
+ (, )
// decode return parameters from external try-call into retVars
- +retVars> := +retVars> (, add(, ))
+ +retVars> := +retVars> (, add(, ))
}
)");
templ("revertNoCode", m_utils.revertReasonIfDebugFunction("Target contract does not contain code"));
@@ -2558,21 +2567,18 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
templ("funSel", IRVariable(_functionCall.expression()).part("functionSelector").name());
templ("address", IRVariable(_functionCall.expression()).part("address").name());
- // Always use the actual return length, and not our calculated expected length, if returndatacopy is supported.
- // This ensures it can catch badly formatted input from external calls.
- if (m_context.evmVersion().supportsReturndata())
- templ("returnSize", "returndatasize()");
- else
- templ("returnSize", to_string(returnInfo.estimatedReturnSize));
-
- templ("reservedReturnSize", returnInfo.dynamicReturnSize ? "0" : to_string(returnInfo.estimatedReturnSize));
+ if (returnInfo.dynamicReturnSize)
+ solAssert(m_context.evmVersion().supportsReturndata());
+ templ("returnDataSizeVar", m_context.newYulVariable());
+ templ("staticReturndataSize", to_string(returnInfo.estimatedReturnSize));
+ templ("supportsReturnData", m_context.evmVersion().supportsReturndata());
string const retVars = IRVariable(_functionCall).commaSeparatedList();
templ("retVars", retVars);
solAssert(retVars.empty() == returnInfo.returnTypes.empty());
templ("abiDecode", m_context.abiFunctions().tupleDecoder(returnInfo.returnTypes, true));
- templ("dynamicReturnSize", returnInfo.dynamicReturnSize);
+ templ("isReturndataSizeDynamic", returnInfo.dynamicReturnSize);
templ("noTryCall", !_functionCall.annotation().tryCall);
diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json
index bb3083af9..238934a3f 100644
--- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json
+++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json
@@ -265,34 +265,39 @@ sub_0: assembly {
return
/* \"C\":403:411 this.f() */
tag_36:
- /* \"C\":79:428 contract C... */
swap1
swap2
pop
- /* \"C\":403:411 this.f() */
+ 0x20
+ swap1
returndatasize
+ dup3
+ gt
+ tag_41
+ jumpi
+ tag_42:
/* \"C\":79:428 contract C... */
0x1f
+ dup3
add
not(0x1f)
and
- dup3
+ dup4
add
swap1
0xffffffffffffffff
dup3
gt
- dup4
+ dup5
dup4
lt
or
- tag_41
+ tag_43
jumpi
pop
- tag_40
swap3
/* \"C\":403:411 this.f() */
- tag_43
+ tag_45
/* \"C\":392:422 stateVar + this.f() + immutVar */
tag_39
/* \"C\":79:428 contract C... */
@@ -301,34 +306,41 @@ sub_0: assembly {
tag_38
/* \"C\":79:428 contract C... */
swap4
+ tag_40
+ swap7
0x40
mstore
/* \"C\":403:411 this.f() */
- returndatasize
dup2
add
swap1
tag_6
jump\t// in
- tag_43:
+ tag_45:
swap3
pop
swap3
jump(tag_37)
/* \"C\":79:428 contract C... */
- tag_41:
+ tag_43:
shl(0xe0, 0x4e487b71)
dup2
mstore
mstore(0x04, 0x41)
0x24
- swap4
+ swap5
+ pop
+ swap3
pop
- swap2
pop
pop
revert
/* \"C\":403:411 this.f() */
+ tag_41:
+ returndatasize
+ swap2
+ pop
+ jump(tag_42)
tag_34:
/* \"C\":79:428 contract C... */
swap3
@@ -345,10 +357,10 @@ sub_0: assembly {
swap1
revert
tag_32:
- tag_44
+ tag_46
tag_4
jump\t// in
- tag_44:
+ tag_46:
jump(tag_33)
/* \"C\":117:119 41 */
tag_4:
@@ -373,9 +385,9 @@ sub_0: assembly {
dup5
sgt
and
- tag_45
+ tag_47
jumpi
- tag_46:
+ tag_48:
shl(0xff, 0x01)
dup3
swap1
@@ -383,25 +395,25 @@ sub_0: assembly {
dup4
slt
and
- tag_47
+ tag_49
jumpi
add
swap1
jump\t// out
- tag_47:
- tag_49
+ tag_49:
+ tag_51
tag_4
jump\t// in
- tag_49:
+ tag_51:
add
swap1
jump\t// out
- tag_45:
- tag_50
+ tag_47:
+ tag_52
tag_4
jump\t// in
- tag_50:
- jump(tag_46)
+ tag_52:
+ jump(tag_48)
/* \"C\":79:428 contract C... */
tag_6:
swap1
@@ -410,12 +422,12 @@ sub_0: assembly {
swap2
sub
slt
- tag_51
+ tag_53
jumpi
mload
swap1
jump\t// out
- tag_51:
+ tag_53:
pop
pop
0x00
@@ -732,34 +744,39 @@ sub_0: assembly {
return
/* \"C\":403:411 this.f() */
tag_36:
- /* \"D\":91:166 contract D is C(3)... */
swap1
swap2
pop
- /* \"C\":403:411 this.f() */
+ 0x20
+ swap1
returndatasize
+ dup3
+ gt
+ tag_41
+ jumpi
+ tag_42:
/* \"D\":91:166 contract D is C(3)... */
0x1f
+ dup3
add
not(0x1f)
and
- dup3
+ dup4
add
swap1
0xffffffffffffffff
dup3
gt
- dup4
+ dup5
dup4
lt
or
- tag_41
+ tag_43
jumpi
pop
- tag_40
swap3
/* \"C\":403:411 this.f() */
- tag_43
+ tag_45
/* \"C\":392:422 stateVar + this.f() + immutVar */
tag_39
/* \"D\":91:166 contract D is C(3)... */
@@ -768,34 +785,41 @@ sub_0: assembly {
tag_38
/* \"D\":91:166 contract D is C(3)... */
swap4
+ tag_40
+ swap7
0x40
mstore
/* \"C\":403:411 this.f() */
- returndatasize
dup2
add
swap1
tag_6
jump\t// in
- tag_43:
+ tag_45:
swap3
pop
swap3
jump(tag_37)
/* \"D\":91:166 contract D is C(3)... */
- tag_41:
+ tag_43:
shl(0xe0, 0x4e487b71)
dup2
mstore
mstore(0x04, 0x41)
0x24
- swap4
+ swap5
+ pop
+ swap3
pop
- swap2
pop
pop
revert
/* \"C\":403:411 this.f() */
+ tag_41:
+ returndatasize
+ swap2
+ pop
+ jump(tag_42)
tag_34:
/* \"D\":91:166 contract D is C(3)... */
swap3
@@ -812,10 +836,10 @@ sub_0: assembly {
swap1
revert
tag_32:
- tag_44
+ tag_46
tag_4
jump\t// in
- tag_44:
+ tag_46:
jump(tag_33)
/* \"C\":117:119 41 */
tag_4:
@@ -840,9 +864,9 @@ sub_0: assembly {
dup5
sgt
and
- tag_45
+ tag_47
jumpi
- tag_46:
+ tag_48:
shl(0xff, 0x01)
dup3
swap1
@@ -850,25 +874,25 @@ sub_0: assembly {
dup4
slt
and
- tag_47
+ tag_49
jumpi
add
swap1
jump\t// out
- tag_47:
- tag_49
+ tag_49:
+ tag_51
tag_4
jump\t// in
- tag_49:
+ tag_51:
add
swap1
jump\t// out
- tag_45:
- tag_50
+ tag_47:
+ tag_52
tag_4
jump\t// in
- tag_50:
- jump(tag_46)
+ tag_52:
+ jump(tag_48)
/* \"D\":91:166 contract D is C(3)... */
tag_6:
swap1
@@ -877,12 +901,12 @@ sub_0: assembly {
swap2
sub
slt
- tag_51
+ tag_53
jumpi
mload
swap1
jump\t// out
- tag_51:
+ tag_53:
pop
pop
0x00
diff --git a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json
index 6b3c5661e..f593301bc 100644
--- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json
+++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json
@@ -563,18 +563,24 @@ object \"C_54\" {
let expr_47
if _12 {
+ let _13 := 32
+
+ if gt(_13, returndatasize()) {
+ _13 := returndatasize()
+ }
+
// update freeMemoryPointer according to dynamic return size
- finalize_allocation(_10, returndatasize())
+ finalize_allocation(_10, _13)
// decode return parameters from external try-call into retVars
- expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, returndatasize()))
+ expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13))
}
/// @src 0:399:418 \"stateVar + this.f()\"
let expr_48 := checked_add_t_int256(expr_44, expr_47)
/// @src 0:421:429 \"immutVar\"
- let _13 := loadimmutable(\"8\")
- let expr_49 := _13
+ let _14 := loadimmutable(\"8\")
+ let expr_49 := _14
/// @src 0:399:429 \"stateVar + this.f() + immutVar\"
let expr_50 := checked_add_t_int256(expr_48, expr_49)
@@ -718,8 +724,10 @@ object \"C_54\" {
/// @src 0:410:418 \"this.f()\"
if _4
{
+ let _5 := 32
+ if gt(_5, returndatasize()) { _5 := returndatasize() }
/// @src 0:79:435 \"contract C...\"
- let newFreePtr := add(_3, and(add(/** @src 0:410:418 \"this.f()\" */ returndatasize(), /** @src 0:79:435 \"contract C...\" */ 31), not(31)))
+ let newFreePtr := add(_3, and(add(_5, 31), not(31)))
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _3))
{
mstore(_1, shl(224, 0x4e487b71))
@@ -728,7 +736,7 @@ object \"C_54\" {
}
mstore(64, newFreePtr)
/// @src 0:410:418 \"this.f()\"
- expr := abi_decode_int256_fromMemory(_3, add(_3, returndatasize()))
+ expr := abi_decode_int256_fromMemory(_3, add(_3, _5))
}
/// @src 0:399:418 \"stateVar + this.f()\"
let expr_1 := checked_add_int256(ret, expr)
@@ -1402,18 +1410,24 @@ object \"D_72\" {
let expr_47
if _12 {
+ let _13 := 32
+
+ if gt(_13, returndatasize()) {
+ _13 := returndatasize()
+ }
+
// update freeMemoryPointer according to dynamic return size
- finalize_allocation(_10, returndatasize())
+ finalize_allocation(_10, _13)
// decode return parameters from external try-call into retVars
- expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, returndatasize()))
+ expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13))
}
/// @src 0:399:418 \"stateVar + this.f()\"
let expr_48 := checked_add_t_int256(expr_44, expr_47)
/// @src 0:421:429 \"immutVar\"
- let _13 := loadimmutable(\"8\")
- let expr_49 := _13
+ let _14 := loadimmutable(\"8\")
+ let expr_49 := _14
/// @src 0:399:429 \"stateVar + this.f() + immutVar\"
let expr_50 := checked_add_t_int256(expr_48, expr_49)
@@ -1565,8 +1579,10 @@ object \"D_72\" {
/// @src 0:410:418 \"this.f()\"
if _4
{
+ let _5 := 32
+ if gt(_5, returndatasize()) { _5 := returndatasize() }
/// @src 1:91:166 \"contract D is C(3)...\"
- let newFreePtr := add(_3, and(add(/** @src 0:410:418 \"this.f()\" */ returndatasize(), /** @src 1:91:166 \"contract D is C(3)...\" */ 31), not(31)))
+ let newFreePtr := add(_3, and(add(_5, 31), not(31)))
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _3))
{
mstore(_1, shl(224, 0x4e487b71))
@@ -1575,7 +1591,7 @@ object \"D_72\" {
}
mstore(64, newFreePtr)
/// @src 0:410:418 \"this.f()\"
- expr := abi_decode_int256_fromMemory(_3, add(_3, returndatasize()))
+ expr := abi_decode_int256_fromMemory(_3, add(_3, _5))
}
/// @src 0:399:418 \"stateVar + this.f()\"
let expr_1 := checked_add_int256(ret, expr)
diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol
index 64ca83041..c386cf3e8 100644
--- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol
+++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol
@@ -60,10 +60,10 @@ contract C {
// compileViaYul: also
// ----
// test_bytes() ->
-// gas irOptimized: 371847
+// gas irOptimized: 371919
// gas legacy: 418955
// gas legacyOptimized: 326783
// test_uint256() ->
-// gas irOptimized: 522929
+// gas irOptimized: 523001
// gas legacy: 586784
// gas legacyOptimized: 451529
diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol
index 3c1ffa6cf..cc1a182c9 100644
--- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol
+++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol
@@ -26,6 +26,6 @@ contract C {
// ----
// library: L
// f() -> 8, 7, 1, 2, 7, 12
-// gas irOptimized: 167672
+// gas irOptimized: 167696
// gas legacy: 169347
// gas legacyOptimized: 167269
diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol
index 1c4e8d7a2..9deed97f1 100644
--- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol
+++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol
@@ -61,10 +61,10 @@ contract C {
// compileViaYul: also
// ----
// test_bytes() ->
-// gas irOptimized: 371847
+// gas irOptimized: 371919
// gas legacy: 418955
// gas legacyOptimized: 326783
// test_uint256() ->
-// gas irOptimized: 522929
+// gas irOptimized: 523001
// gas legacy: 586784
// gas legacyOptimized: 451529
diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol
index 2aa7a251b..eec062f56 100644
--- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol
+++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol
@@ -32,6 +32,6 @@ contract C is B {
// compileViaYul: also
// ----
// test() -> 77
-// gas irOptimized: 119895
+// gas irOptimized: 119919
// gas legacy: 155093
// gas legacyOptimized: 111550
diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol
index 8d1f1a727..cf5958d45 100644
--- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol
+++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol
@@ -21,6 +21,6 @@ contract C {
// f(uint256[][1]): 32, 32, 0 -> true
// f(uint256[][1]): 32, 32, 1, 42 -> true
// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true
-// gas irOptimized: 171838
+// gas irOptimized: 171842
// gas legacy: 141644
// gas legacyOptimized: 121532
diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol
index 3b0a73d00..fcf41823e 100644
--- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol
+++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol
@@ -21,6 +21,6 @@ contract B {
// compileViaYul: also
// ----
// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004
-// gas irOptimized: 130097
+// gas irOptimized: 130152
// gas legacy: 234943
// gas legacyOptimized: 132863
diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol
index e9aef6d0d..73f9799d4 100644
--- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol
+++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol
@@ -45,6 +45,6 @@ contract C {
// compileViaYul: also
// ----
// test() -> 5, 6, 7
-// gas irOptimized: 290567
+// gas irOptimized: 298983
// gas legacy: 452172
// gas legacyOptimized: 285017
diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol
index 87280f6a4..ee91ce7f7 100644
--- a/test/libsolidity/semanticTests/array/reusing_memory.sol
+++ b/test/libsolidity/semanticTests/array/reusing_memory.sol
@@ -26,6 +26,6 @@ contract Main {
// compileViaYul: also
// ----
// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1
-// gas irOptimized: 113552
+// gas irOptimized: 113598
// gas legacy: 126596
// gas legacyOptimized: 113823
diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol
index 759c58d30..cc303899a 100644
--- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol
+++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol
@@ -26,6 +26,6 @@ contract Creator {
// compileViaYul: also
// ----
// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8
-// gas irOptimized: 443921
+// gas irOptimized: 443960
// gas legacy: 590683
// gas legacyOptimized: 448326
diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol
index 7210ac269..ffe0fb8c2 100644
--- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol
+++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol
@@ -26,6 +26,6 @@ contract Creator {
// compileViaYul: also
// ----
// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h"
-// gas irOptimized: 300765
+// gas irOptimized: 300804
// gas legacy: 428917
// gas legacyOptimized: 298128
diff --git a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol
index 690f555dc..5ec47a4a9 100644
--- a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol
+++ b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol
@@ -17,7 +17,7 @@ contract C {
// compileViaYul: also
// ----
// constructor() ->
-// gas irOptimized: 177344
+// gas irOptimized: 173672
// gas legacy: 250376
// gas legacyOptimized: 174522
// deposit(bytes32), 18 wei: 0x1234 ->
diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol
index 2da7c2dd6..685d8a7de 100644
--- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol
+++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol
@@ -17,7 +17,7 @@ contract D {
// compileViaYul: also
// ----
// constructor(): 2 ->
-// gas irOptimized: 200295
+// gas irOptimized: 203967
// gas legacy: 245842
// gas legacyOptimized: 195676
// f() -> 2
diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol
index 0b0633c6d..a768a2836 100644
--- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol
+++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol
@@ -18,7 +18,7 @@ contract D {
// compileViaYul: also
// ----
// constructor(): 2 ->
-// gas irOptimized: 200458
+// gas irOptimized: 204130
// gas legacy: 246202
// gas legacyOptimized: 195914
// f() -> 2
diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol
index 942faa048..030aeaa10 100644
--- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol
+++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol
@@ -25,7 +25,7 @@ contract C {
// compileViaYul: also
// ----
// constructor(), 1 ether ->
-// gas irOptimized: 308423
+// gas irOptimized: 315341
// gas legacy: 465314
// gas legacyOptimized: 304481
// f(uint256): 0 -> FAILURE
diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol
index ce8d29b8b..cfbf1bcc1 100644
--- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol
+++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol
@@ -27,7 +27,7 @@ contract C {
// revertStrings: debug
// ----
// constructor(), 1 ether ->
-// gas irOptimized: 445767
+// gas irOptimized: 452673
// gas legacy: 834272
// gas legacyOptimized: 510004
// f(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code"
diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol
index 4862f3b4c..2ebf8740d 100644
--- a/test/libsolidity/semanticTests/functionCall/failed_create.sol
+++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol
@@ -18,7 +18,7 @@ contract C {
// compileViaYul: also
// ----
// constructor(), 20 wei
-// gas irOptimized: 213663
+// gas irOptimized: 219285
// gas legacy: 294569
// gas legacyOptimized: 174699
// f(uint256): 20 -> 1370859564726510389319704988634906228201275401179
@@ -26,7 +26,7 @@ contract C {
// f(uint256): 20 -> FAILURE
// x() -> 1
// stack(uint256): 1023 -> FAILURE
-// gas irOptimized: 304303
+// gas irOptimized: 314884
// gas legacy: 483942
// gas legacyOptimized: 298807
// x() -> 1
diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol
index a4c3fb3dd..4321753d6 100644
--- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol
+++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol
@@ -41,7 +41,7 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
-// gas irOptimized: 274154
+// gas irOptimized: 283040
// gas legacy: 402654
// gas legacyOptimized: 274470
// sendAmount(uint256): 5 -> 5
diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol
index 5b39dda48..2f89517b7 100644
--- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol
+++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol
@@ -40,7 +40,7 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
-// gas irOptimized: 274154
+// gas irOptimized: 283040
// gas legacy: 402654
// gas legacyOptimized: 274470
// sendAmount(uint256): 5 -> 5
diff --git a/test/libsolidity/semanticTests/functionCall/return_size_bigger_than_expected.sol b/test/libsolidity/semanticTests/functionCall/return_size_bigger_than_expected.sol
new file mode 100644
index 000000000..c7a1d12bf
--- /dev/null
+++ b/test/libsolidity/semanticTests/functionCall/return_size_bigger_than_expected.sol
@@ -0,0 +1,31 @@
+interface ShortReturn {
+ function f() external pure returns (bytes32);
+}
+contract LongReturn {
+ function f() external pure returns (uint[20] memory) {}
+}
+
+contract Test {
+ function test() public returns (uint) {
+ LongReturn longReturn = new LongReturn();
+ uint freeMemoryBefore;
+ assembly {
+ freeMemoryBefore := mload(0x40)
+ }
+
+ ShortReturn(address(longReturn)).f();
+
+ uint freeMemoryAfter;
+
+ assembly {
+ freeMemoryAfter := mload(0x40)
+ }
+
+ return freeMemoryAfter - freeMemoryBefore;
+ }
+}
+// ====
+// compileViaYul: true
+// ----
+// test() -> 0x20
+// gas legacy: 131966
diff --git a/test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected.sol b/test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected.sol
new file mode 100644
index 000000000..5f39b877e
--- /dev/null
+++ b/test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected.sol
@@ -0,0 +1,32 @@
+interface LongReturn {
+ function f() external pure returns (uint[20] memory);
+}
+contract ShortReturn {
+ function f() external pure returns (bytes32) {}
+}
+
+contract Test {
+ function test() public returns (uint) {
+ ShortReturn shortReturn = new ShortReturn();
+ uint freeMemoryBefore;
+ assembly {
+ freeMemoryBefore := mload(0x40)
+ }
+
+ LongReturn(address(shortReturn)).f();
+
+ uint freeMemoryAfter;
+
+ assembly {
+ freeMemoryAfter := mload(0x40)
+ }
+
+ return freeMemoryAfter - freeMemoryBefore;
+ }
+}
+// ====
+// EVMVersion: <=homestead
+// compileViaYul: true
+// ----
+// test() -> 0x0500
+// gas legacy: 131966
diff --git a/test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected_evm_version_after_homestead.sol b/test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected_evm_version_after_homestead.sol
new file mode 100644
index 000000000..225832275
--- /dev/null
+++ b/test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected_evm_version_after_homestead.sol
@@ -0,0 +1,34 @@
+interface LongReturn {
+ function f() external pure returns (uint[20] memory);
+}
+contract ShortReturn {
+ function f() external pure returns (bytes32) {}
+}
+
+contract Test {
+ function test() public returns (uint) {
+ ShortReturn shortReturn = new ShortReturn();
+ uint freeMemoryBefore;
+ assembly {
+ freeMemoryBefore := mload(0x40)
+ }
+
+ // This reverts. The external call succeeds but ABI decoding fails due to the returned
+ // `bytes32` being much shorter than the expected `uint[20]`.
+ LongReturn(address(shortReturn)).f();
+
+ uint freeMemoryAfter;
+
+ assembly {
+ freeMemoryAfter := mload(0x40)
+ }
+
+ return freeMemoryAfter - freeMemoryBefore;
+ }
+}
+// ====
+// EVMVersion: >homestead
+// compileViaYul: true
+// ----
+// test() -> FAILURE
+// gas legacy: 131966
diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol
index 840a8761b..e834663d0 100644
--- a/test/libsolidity/semanticTests/immutable/multi_creation.sol
+++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol
@@ -29,7 +29,7 @@ contract C {
// compileViaYul: also
// ----
// f() -> 3, 7, 5
-// gas irOptimized: 127302
+// gas irOptimized: 127347
// gas legacy: 151334
// gas legacyOptimized: 125166
// x() -> 7
diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol
index 8f3584a9d..a15650992 100644
--- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol
+++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol
@@ -25,6 +25,6 @@ contract B {
// compileViaYul: also
// ----
// g() -> 42
-// gas irOptimized: 111770
+// gas irOptimized: 111794
// gas legacy: 185053
// gas legacyOptimized: 114598
diff --git a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol
index 94cd46a2d..e6f94bdcf 100644
--- a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol
+++ b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol
@@ -42,7 +42,7 @@ contract Main {
// compileViaYul: also
// ----
// constructor(), 22 wei ->
-// gas irOptimized: 276469
+// gas irOptimized: 284287
// gas legacy: 402045
// gas legacyOptimized: 266772
// getFlag() -> true
diff --git a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol
index 5af1e5cdc..8d37ed809 100644
--- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol
+++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol
@@ -18,7 +18,7 @@ contract ClientReceipt {
// compileViaYul: also
// ----
// constructor(), 2000 wei ->
-// gas irOptimized: 184076
+// gas irOptimized: 188162
// gas legacy: 235195
// gas legacyOptimized: 176766
// balance -> 1500
diff --git a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol
index 6b13ee09c..ac61fad71 100644
--- a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol
+++ b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol
@@ -25,6 +25,6 @@ contract Test {
// ----
// library: Lib
// f() -> 4, 0x11
-// gas irOptimized: 115822
+// gas irOptimized: 115874
// gas legacy: 135952
// gas legacyOptimized: 119643
diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol
index d85f90694..e8d22c279 100644
--- a/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol
+++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol
@@ -22,6 +22,6 @@ contract Test {
// ----
// library: Lib
// f() -> 1, 0, 0x2a, 0x17, 0, 0x63
-// gas irOptimized: 119757
+// gas irOptimized: 119561
// gas legacy: 124793
// gas legacyOptimized: 119694
diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol
index 9192fdfe3..86e7fa3d7 100644
--- a/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol
+++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol
@@ -20,6 +20,6 @@ contract Test {
// ----
// library: Lib
// f() -> 1, 0, 0x2a, 0x17, 0, 0x63
-// gas irOptimized: 120471
+// gas irOptimized: 120572
// gas legacy: 125245
// gas legacyOptimized: 120153
diff --git a/test/libsolidity/semanticTests/libraries/using_library_structs.sol b/test/libsolidity/semanticTests/libraries/using_library_structs.sol
index 4348c377c..116887fd5 100644
--- a/test/libsolidity/semanticTests/libraries/using_library_structs.sol
+++ b/test/libsolidity/semanticTests/libraries/using_library_structs.sol
@@ -23,5 +23,5 @@ contract Test {
// ----
// library: Lib
// f() -> 7, 8
-// gas irOptimized: 101869
+// gas irOptimized: 101820
// gas legacy: 101504
diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol
index af9c7e76b..4ce8b5149 100644
--- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol
+++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol
@@ -22,6 +22,6 @@ contract A {
// compileViaYul: also
// ----
// f(), 10 ether -> 3007, 3008, 3009
-// gas irOptimized: 272338
+// gas irOptimized: 272413
// gas legacy: 422501
// gas legacyOptimized: 287472
diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol
index bd7e2fe9c..56ad74c54 100644
--- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol
+++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol
@@ -51,7 +51,7 @@ contract C {
// compileViaYul: also
// ----
// test_f() -> true
-// gas irOptimized: 122413
+// gas irOptimized: 122364
// gas legacy: 126168
// gas legacyOptimized: 123199
// test_g() -> true
diff --git a/test/libsolidity/semanticTests/various/senders_balance.sol b/test/libsolidity/semanticTests/various/senders_balance.sol
index 600e72e3e..1c456f1d4 100644
--- a/test/libsolidity/semanticTests/various/senders_balance.sol
+++ b/test/libsolidity/semanticTests/various/senders_balance.sol
@@ -19,7 +19,7 @@ contract D {
// compileViaYul: also
// ----
// constructor(), 27 wei ->
-// gas irOptimized: 175261
+// gas irOptimized: 178933
// gas legacy: 222977
// gas legacyOptimized: 169779
// f() -> 27
diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol
index ba4e7426a..30a2d9f65 100644
--- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol
+++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol
@@ -22,6 +22,6 @@ contract C {
// compileViaYul: also
// ----
// g() -> 2, 6
-// gas irOptimized: 178822
+// gas irOptimized: 178812
// gas legacy: 180762
// gas legacyOptimized: 179481
diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/value_complex.sol
index bebf7557f..5d8bda5dd 100644
--- a/test/libsolidity/semanticTests/various/value_complex.sol
+++ b/test/libsolidity/semanticTests/various/value_complex.sol
@@ -22,7 +22,7 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
-// gas irOptimized: 185891
+// gas irOptimized: 192113
// gas legacy: 265006
// gas legacyOptimized: 182842
// sendAmount(uint256): 5 -> 8
diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/value_insane.sol
index 9edd8061a..0b2b1735b 100644
--- a/test/libsolidity/semanticTests/various/value_insane.sol
+++ b/test/libsolidity/semanticTests/various/value_insane.sol
@@ -21,7 +21,7 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
-// gas irOptimized: 187835
+// gas irOptimized: 194261
// gas legacy: 266728
// gas legacyOptimized: 184762
// sendAmount(uint256): 5 -> 8
diff --git a/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol
index 497dd36c8..05b7e668b 100644
--- a/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol
+++ b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol
@@ -23,6 +23,6 @@ contract C {
// compileViaYul: also
// ----
// f() ->
-// gas irOptimized: 113096
+// gas irOptimized: 112998
// gas legacy: 112937
// gas legacyOptimized: 112608