diff --git a/Changelog.md b/Changelog.md index e73633d7022a..c17b7e0b3eb9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: + * ABI Encoder: When encoding an empty string coming from storage do not add a superfluous empty slot for data. ### 0.8.14 (2022-05-17) diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index d24dfc07880e..e83f940f51ad 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -699,7 +699,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray( case 0 { // short byte array mstore(pos, and(slotValue, not(0xff))) - ret := add(pos, ) + ret := add(pos, mul(, iszero(iszero(length)))) } case 1 { // long byte array diff --git a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol index 4bf31f705953..6828a1bc91d6 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -17,7 +17,7 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 121735 +// gas irOptimized: 121752 // gas legacy: 123884 // gas legacyOptimized: 119139 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol index 99335817a51b..b005b0183600 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol @@ -35,11 +35,11 @@ contract C { } // ---- // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 -// gas irOptimized: 179895 +// gas irOptimized: 179912 // gas legacy: 180676 // gas legacyOptimized: 180070 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 107274 +// gas irOptimized: 107291 // gas legacy: 107877 // gas legacyOptimized: 107236 // h() -> 0x40, 0x60, 0x00, 0x00 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol index d19bbf6a849a..a8663015097c 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -11,6 +11,6 @@ contract C { } // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 -// gas irOptimized: 202840 +// gas irOptimized: 202864 // gas legacy: 204441 // gas legacyOptimized: 203419 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol index 1c7e2fd7d7f2..d6223c54bc26 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol @@ -10,6 +10,6 @@ contract c { // ---- // test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000 -// gas irOptimized: 109499 +// gas irOptimized: 109515 // gas legacy: 126728 // gas legacyOptimized: 123444 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index b6c0c3ca9882..2a9e75ffe792 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -8,7 +8,7 @@ contract Test { } // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> -// gas irOptimized: 283829 +// gas irOptimized: 284909 // gas legacy: 309607 // gas legacyOptimized: 260566 // m_x() -> 7 diff --git a/test/libsolidity/semanticTests/strings/empty_storage_string.sol b/test/libsolidity/semanticTests/strings/empty_storage_string.sol new file mode 100644 index 000000000000..70d85f24b4b0 --- /dev/null +++ b/test/libsolidity/semanticTests/strings/empty_storage_string.sol @@ -0,0 +1,100 @@ +contract C { + + string uninitializedString; + string emptyString = ""; + string nonEmptyString = "This is a non empty string"; + string nonEmptyString2 = "Another string"; + bytes uninitializedBytes; + bytes emptyBytes = ""; + error EmptyError(string); + event EmptyEvent(string); + + function f() public returns (string memory) { + return uninitializedString; + } + + function g() public returns (string memory, string memory) { + return (uninitializedString, emptyString); + } + + function h() public returns (string memory, string memory) { + return (uninitializedString, nonEmptyString); + } + + function i() public returns (string memory, string memory) { + return (nonEmptyString, emptyString); + } + + function j(string calldata _s) public returns (string memory) { + return _s; + } + + function k() public returns (string memory) { + nonEmptyString2 = ""; + return nonEmptyString2; + } + + function l(string calldata _s) public returns (bytes memory) { + return abi.encode(_s); + } + + function m() public returns (string memory) { + bytes memory b = abi.encode(emptyString); + return string(b); + } + + function n() public { + revert EmptyError(uninitializedString); + } + + function o() public { + emit EmptyEvent(emptyString); + } + + function p() public { + emit EmptyEvent(""); + } + + function q() public returns (bytes memory) { + return uninitializedBytes; + } + + function r() public returns (bytes memory) { + emptyBytes = abi.encode(""); + return emptyBytes; + } + + function s() public returns (bytes memory) { + emptyBytes = abi.encode(uninitializedString); + return emptyBytes; + } + + function set(string calldata _s) public { + nonEmptyString = _s; + } + + function get() public returns (string memory) { + return nonEmptyString; + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x20, 0 +// g() -> 0x40, 0x60, 0, 0 +// h() -> 0x40, 0x60, 0, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328 +// i() -> 0x40, 0x80, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328, 0 +// j(string): 0x20, 0, "" -> 0x20, 0 +// k() -> 0x20, 0 +// l(string): 0x20, 0, "" -> 0x20, 0x40, 0x20, 0 +// m() -> 0x20, 0x40, 0x20, 0 +// n() -> FAILURE, hex"d3f13430", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000000" +// o() -> +// ~ emit EmptyEvent(string): 0x20, 0x00 +// p() -> +// ~ emit EmptyEvent(string): 0x20, 0x00 +// q() -> 0x20, 0 +// r() -> 0x20, 0x40, 0x20, 0 +// s() -> 0x20, 0x40, 0x20, 0 +// set(string): 0x20, 0, "" -> +// get() -> 0x20, 0 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index a91965580b39..dd0338e28f37 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -16,7 +16,7 @@ contract C { // compileToEwasm: also // ---- // constructor() -> -// gas irOptimized: 192317 +// gas irOptimized: 193397 // gas legacy: 240889 // gas legacyOptimized: 155314 // initCode() -> 0x20, 0 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 2e7c677a61bd..da3620d19fd3 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -20,6 +20,6 @@ contract C { // ---- // g() -> 2, 6 -// gas irOptimized: 178805 +// gas irOptimized: 178822 // gas legacy: 180753 // gas legacyOptimized: 179472