From 886bf48051632d01b745aa8f542b965276454e57 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 2 Dec 2025 16:11:56 -0300 Subject: [PATCH 01/33] Set version to 0.8.32 --- CMakeLists.txt | 2 +- Changelog.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e477cf3a8dd..f4d67e243bab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.8.31") +set(PROJECT_VERSION "0.8.32") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) diff --git a/Changelog.md b/Changelog.md index a75193adb218..5cd6133f2cd8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,12 @@ +### 0.8.32 (unreleased) + +Language Features: + +Compiler Features: + +Bugfixes: + + ### 0.8.31 (2025-12-03) Language Features: From b7ce492bb651f1f80d5d5a4d675d97972387e70b Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Wed, 3 Dec 2025 16:35:56 -0300 Subject: [PATCH 02/33] Move changelog entries to correct section --- Changelog.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5cd6133f2cd8..1aa6bc64b2f4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,18 +10,18 @@ Bugfixes: ### 0.8.31 (2025-12-03) Language Features: -* Yul: Introduce builtin `clz(x)` for counting the number of leading zero bits in a 256-bit word. - - -Compiler Features: * Custom Storage Layout: Allow using `constant` state variables in the base slot expression. * DocString Parser: Warn about deprecation of inline assembly special comment `memory-safe-assembly`. -* ethdebug: Experimental support for instructions and source locations under EOF. -* EVM: Set default EVM Version to `osaka`. * Syntax Checker: Warn about deprecation of ABI coder v1. * Syntax Checker: Warn about deprecation of virtual modifiers. * Type Checker: Warn about deprecation of `send` and `transfer` functions on instances of `address`. * Type Checker: Warn about deprecation of comparisons between variables of contract types. +* Yul: Introduce builtin `clz(x)` for counting the number of leading zero bits in a 256-bit word. + + +Compiler Features: +* ethdebug: Experimental support for instructions and source locations under EOF. +* EVM: Set default EVM Version to `osaka`. Bugfixes: From ec00d77b89dae6444ef689d2c6c7b21a1c19f638 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Wed, 3 Dec 2025 13:53:06 -0300 Subject: [PATCH 03/33] Update release checklist with docker login info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- ReleaseChecklist.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index b78edc2de2fd..9c3b2f89682d 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -42,6 +42,7 @@ At least a day before the release: - [ ] Get the posts reviewed and approved **before the release starts**. ### Changelog +- [ ] Ensure that all changelog entries are correctly classified as language or compiler features. - [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it. - [ ] Update the changelog to include a release date. - [ ] Run `scripts/update_bugs_by_version.py` to regenerate `bugs_by_version.json` from the changelog and `bugs.json`. @@ -76,6 +77,7 @@ At least a day before the release: ### Docker - [ ] Make sure `docker-buildx` is installed. +- [ ] Run `echo $GHCR_TOKEN | docker login ghcr.io --username $GH_USERNAME --password-stdin` where `$GH_USERNAME` is your GitHub username and `$GHCR_TOKEN` is a PAT with `write:packages` scope. - [ ] Run `./scripts/docker_deploy_manual.sh v$VERSION`. ### Release solc-js From 7b39f83127382f9fb057567cc04035cd838e5627 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 4 Dec 2025 15:09:49 -0300 Subject: [PATCH 04/33] Copy libevmone to Linux ARM machine --- scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.arm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.arm b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.arm index a24549d4b830..663928220a0e 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.arm +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.arm @@ -22,7 +22,7 @@ # (c) 2016-2025 solidity contributors. #------------------------------------------------------------------------------ FROM --platform=linux/arm64 buildpack-deps:noble AS base -LABEL version="1" +LABEL version="2" ARG DEBIAN_FRONTEND=noninteractive @@ -104,6 +104,7 @@ RUN <<-EOF EOF FROM base +COPY --from=libraries /usr/local/lib/libevmone* /usr/lib COPY --from=libraries /usr/lib /usr/lib COPY --from=libraries /usr/bin /usr/bin COPY --from=libraries /usr/include /usr/include From 6ac7d73b23d9e7b1c6fbb02fcd1cde77537bd2e3 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Thu, 4 Dec 2025 18:33:31 -0300 Subject: [PATCH 05/33] Disable partial clone and fetch all objects on alpine --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6255d2834e3c..6109d056128f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1931,6 +1931,12 @@ jobs: # This job is only meant to run nightly so build time is not an issue. docker_layer_caching: false - checkout + - run: + name: Disable partial clone and fetch all objects + command: | + git config remote.origin.promisor false + git config --unset remote.origin.partialclonefilter + git fetch --refetch origin - run: name: Build and tag the container command: scripts/docker_deploy_manual.sh develop "file://$PWD" --no-push From 37653a0f95d4c3330e3d2564cd77946b963043dd Mon Sep 17 00:00:00 2001 From: blishko Date: Fri, 5 Dec 2025 11:24:57 +0100 Subject: [PATCH 06/33] SMTChecker: Use Eldarica in more tests Eldarica is more reliable on Z3 and results in fewer differences of behaviour across different platforms. The disadvantage is that Eldarica often takes longer to solve the problems than Z3. --- .../external_calls/external_call_indirect_2.sol | 2 +- .../external_calls/external_call_indirect_5.sol | 1 + .../smtCheckerTests/functions/functions_external_2.sol | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol index 16779bb89a1f..d6575fdc22ba 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol @@ -47,7 +47,7 @@ contract C { // ==== // SMTEngine: chc // SMTExtCalls: trusted -// SMTIgnoreOS: macos +// SMTSolvers: eld // ---- // Warning 6328: (434-455): CHC: Assertion violation happens here. // Warning 6328: (1270-1291): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol index 26d39838ef4b..da3077c84aa1 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol @@ -46,6 +46,7 @@ contract C { // SMTContract: C // SMTEngine: chc // SMTExtCalls: trusted +// SMTSolvers: eld // ---- // Warning 6328: (601-622): CHC: Assertion violation happens here. // Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol b/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol index d3373b62d63a..cbac9fbbba3b 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol @@ -20,9 +20,9 @@ contract C } } // ==== -// SMTEngine: all +// SMTEngine: chc // SMTIgnoreCex: yes -// SMTIgnoreOS: macos +// SMTSolvers: eld // ---- // Warning 6328: (234-253): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From bdf3c50ea0229d086e6b38a1c520f45204a36ca7 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 5 Dec 2025 19:08:54 -0300 Subject: [PATCH 07/33] Update fmtlib to 12.1.0 --- deps/fmtlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/fmtlib b/deps/fmtlib index 40626af88bd7..407c905e45ad 160000 --- a/deps/fmtlib +++ b/deps/fmtlib @@ -1 +1 @@ -Subproject commit 40626af88bd7df9a5fb80be7b25ac85b122d6c21 +Subproject commit 407c905e45ad75fc29bf0f9bb7c5c2fd3475976f From e0773b9fadc5cd6fcf718314ce511500501f8a56 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 2 Dec 2025 23:21:47 -0300 Subject: [PATCH 08/33] run soltest and cli tests on arm --- .circleci/config.yml | 49 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6109d056128f..8c7a560183be 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -701,6 +701,11 @@ defaults: requires: - b_ubu_static + - requires_b_ubu_static_arm: &requires_b_ubu_static_arm + <<: *on_all_tags_and_branches + requires: + - b_ubu_static_arm + - requires_b_archlinux: &requires_b_archlinux <<: *on_all_tags_and_branches requires: @@ -1104,7 +1109,7 @@ jobs: - solc/solc-static-linux - matrix_notify_failure_unless_pr - b_ubu_static_arm: + b_ubu_static_arm: &b_ubu_static_arm <<: *base_ubuntu2404_arm_large environment: <<: *base_ubuntu2404_arm_large_env @@ -1293,6 +1298,28 @@ jobs: steps: - soltest_all + t_ubu_arm_soltest: &t_ubu_arm_soltest + <<: *base_ubuntu2404_arm_medium + parallelism: 20 + environment: + <<: *base_ubuntu2404_arm_medium_env + EVM: << pipeline.parameters.evm-version >> + EOF_VERSION: 0 + OPTIMIZE: 0 + steps: + - checkout + - attach_workspace: + at: build + - run: + name: Create symbolic link with expected soltest binary name + command: | + ln --symbolic --relative build/test/soltest-linux-arm build/test/soltest + - run_soltest + - store_test_results: + path: test_results/ + - store_artifacts_test_results + - matrix_notify_failure_unless_pr + t_ubu_soltest_deprecated_evm_versions: &t_ubu_soltest_deprecated_evm_versions <<: *base_ubuntu2404_large parallelism: 50 @@ -1355,6 +1382,24 @@ jobs: steps: - cmdline_tests + t_ubu_arm_cli: &t_ubu_arm_cli + <<: *base_ubuntu2404_arm_medium + parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py + steps: + - checkout + - attach_workspace: + at: build + - run: + name: Create symbolic link with expected solc and solfuzzer binaries name + command: | + ln --symbolic --relative build/solc/solc-static-linux-arm build/solc/solc + ln --symbolic --relative build/test/tools/solfuzzer-linux-arm build/test/tools/solfuzzer + - run_cmdline_tests + - store_test_results: + path: test_results/ + - store_artifacts_test_results + - matrix_notify_failure_unless_pr + t_ubu_force_release_cli: &t_ubu_force_release_cli <<: *t_ubu_cli @@ -1991,8 +2036,10 @@ workflows: # Ubuntu build and tests - b_ubu: *requires_nothing - t_ubu_cli: *requires_b_ubu + - t_ubu_arm_cli: *requires_b_ubu_static_arm - t_ubu_locale: *requires_b_ubu - t_ubu_soltest_all: *requires_b_ubu + - t_ubu_arm_soltest: *requires_b_ubu_static_arm - b_ubu_clang: *requires_nothing - t_ubu_clang_soltest: *requires_b_ubu_clang - t_ubu_lsp: *requires_b_ubu From 9763e9f5d0e95f4f3d2920c7bec7e821e24edeea Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 4 Dec 2025 18:25:04 -0300 Subject: [PATCH 09/33] Use new Linux ARM image --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8c7a560183be..69ae1999fc3e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,8 +17,8 @@ parameters: default: "ghcr.io/argotorg/solidity-buildpack-deps@sha256:c0412c53e59ce0c96bde4c08e7332ea12e4cadba9bbac829621947897fa21272" ubuntu-2404-arm-docker-image: type: string - # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404.arm-1 - default: "ghcr.io/argotorg/solidity-buildpack-deps@sha256:6cdb928fa8743d0b5d515c2c489b8d545c541f2370af28d5d3a71532056a0f22" + # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404.arm-2 + default: "ghcr.io/argotorg/solidity-buildpack-deps@sha256:27b03c1c4688e5d69b10e0539460346a3dee3b10b0e04fb406b9707c6f0dd95e" ubuntu-2404-clang-docker-image: type: string # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404.clang-7 From 8d563631f2e9a04555b9149513fd4eae283b0ee1 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sat, 6 Dec 2025 16:09:16 -0300 Subject: [PATCH 10/33] Update nlohmann-json to v3.12.0 --- deps/nlohmann-json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/nlohmann-json b/deps/nlohmann-json index 9cca280a4d0c..55f93686c015 160000 --- a/deps/nlohmann-json +++ b/deps/nlohmann-json @@ -1 +1 @@ -Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 +Subproject commit 55f93686c01528224f448c19128836e7df245f72 From 37ce297ec64d1e32cad82c1fc370a9702a44447b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 10 Dec 2025 11:50:42 +0100 Subject: [PATCH 11/33] contributing.rst: Add a link to the public call agenda --- docs/contributing.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/contributing.rst b/docs/contributing.rst index 45b15e579db0..b5eb3c08ed09 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -34,6 +34,9 @@ the team and contributors are working on, you can join our public team call: The call takes place on `Jitsi `_. +New topics can be freely added to the `agenda `_ +and will be scheduled for discussion on the nearest call. + How to Report Issues ==================== From 51e91352c0b08cf813fe4458a0ea1be3470e14fb Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 3 Dec 2025 17:00:30 +0100 Subject: [PATCH 12/33] Fix constantness of event and error selectors. Reported by https://github.com/argotorg/solidity/issues/13137 --- libsolidity/analysis/TypeChecker.cpp | 27 ++++++++++++++----- .../event_error_selector_pure_assignment.sol | 20 ++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 test/libsolidity/syntaxTests/types/functionTypes/selector/event_error_selector_pure_assignment.sol diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 9e29983bad3b..f5c093dbd411 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3280,18 +3280,31 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) auto const* functionType = dynamic_cast(exprType); functionType && functionType->hasDeclaration() && - dynamic_cast(&functionType->declaration()) && memberName == "selector" ) - if (auto const* parentAccess = dynamic_cast(&_memberAccess.expression())) + { + if (dynamic_cast(&functionType->declaration())) { - bool isPure = *parentAccess->expression().annotation().isPure; - if (auto const* exprInt = dynamic_cast(&parentAccess->expression())) - if (exprInt->name() == "this" || exprInt->name() == "super") - isPure = true; + if (auto const* parentAccess = dynamic_cast(&_memberAccess.expression())) + { + bool isPure = *parentAccess->expression().annotation().isPure; + // Accessing a function selector using `super|this.f.selector`. + if (auto const* exprInt = dynamic_cast(&parentAccess->expression())) + if (exprInt->name() == "this" || exprInt->name() == "super") + isPure = true; - annotation.isPure = isPure; + annotation.isPure = isPure; + } } + // In case of event or error definition the selector is always compile-time constant, as it can be + // a keccak256 hash of the event signature or a function selector in case of an error. + else if ( + dynamic_cast(&functionType->declaration()) || + dynamic_cast(&functionType->declaration()) + ) + annotation.isPure = true; + } + if ( auto const* varDecl = dynamic_cast(annotation.referencedDeclaration); !annotation.isPure.set() && diff --git a/test/libsolidity/syntaxTests/types/functionTypes/selector/event_error_selector_pure_assignment.sol b/test/libsolidity/syntaxTests/types/functionTypes/selector/event_error_selector_pure_assignment.sol new file mode 100644 index 000000000000..263e8f8a1a68 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/functionTypes/selector/event_error_selector_pure_assignment.sol @@ -0,0 +1,20 @@ +event EvExt(); +error ErExt(); + +bytes32 constant eventExtSelectorGlobal = EvExt.selector; +bytes4 constant errorExtSelectorGlobal = ErExt.selector; + +contract C { + event Ev(); + error Er(); + + bytes4 constant errorExtSelector = ErExt.selector; + bytes32 constant eventExtSelector = EvExt.selector; + + bytes4 constant errorSelector = Er.selector; + bytes32 constant eventSelector = Ev.selector; + + bytes4 constant errorSelectorC = C.Er.selector; + bytes32 constant eventSelectorC = C.Ev.selector; +} +// ---- From 4ec10c9343225595cb1d2655f4c66b29349f59c9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 8 Dec 2025 09:56:06 +0100 Subject: [PATCH 13/33] Add the changelog entry. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Changelog.md Co-authored-by: Nikola Matić --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 1aa6bc64b2f4..42d679caa3df 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: Bugfixes: +* TypeChecker: Fix error and event selectors not being considered compile-time constant. ### 0.8.31 (2025-12-03) From befaeda28009ce126bfa3c4b26f2877433e30fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Dec 2025 10:27:20 +0100 Subject: [PATCH 14/33] Always update stale gas expectations, even if below threshold --- test/libsolidity/SemanticTest.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 1b66dd60fffb..890a51596af8 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -579,22 +579,16 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp io_test.call().expectations.gasUsedForCodeDeposit.count(setting) ); - // We don't check gas if enforce gas cost is not active - // or test is run with abi encoder v1 only - // or gas used less than threshold for enforcing feature - // or the test has used up all available gas (test will fail anyway) - // or setting is "ir" and it's not included in expectations - // or if the called function is an isoltest builtin e.g. `smokeTest` or `storageEmpty` - if ( - !m_enforceGasCost || - m_gasUsed < m_enforceGasCostMinValue || - m_gasUsed >= InitialGas || - (setting == "ir" && io_test.call().expectations.gasUsedExcludingCode.count(setting) == 0) || - io_test.call().kind == FunctionCall::Kind::Builtin - ) + bool uninteresting = + m_gasUsed < m_enforceGasCostMinValue || // gas used less than threshold for enforcing feature + m_gasUsed >= InitialGas || // test has used up all available gas (test will fail anyway) + setting == "ir" || + io_test.call().kind == FunctionCall::Kind::Builtin; // isoltest builtin e.g. `smokeTest` or `storageEmpty` + bool gasValueMissing = !io_test.call().expectations.gasUsedExcludingCode.contains(setting); + if (!m_enforceGasCost || (gasValueMissing && uninteresting)) return true; - solAssert(!m_runWithABIEncoderV1Only, ""); + solAssert(!m_runWithABIEncoderV1Only); // NOTE: Cost excluding code is unlikely to be negative but it may still be possible due to refunds. // We'll deal with it when we actually have a test case like that. From 16ab579bdb49afd7d5d10af011c6348df0d90028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Dec 2025 11:30:41 +0100 Subject: [PATCH 15/33] Update stale gas expectations that dropped below the default 100k threshold --- ...ode_v2_in_modifier_used_in_v1_contract.sol | 3 +- .../abiEncoderV2/calldata_array.sol | 4 +- .../array/array_storage_length_access.sol | 2 +- ...rray_storage_push_empty_length_address.sol | 6 +- .../array/array_storage_push_pop.sol | 6 +- .../array/byte_array_storage_layout.sol | 10 ++-- .../copying/array_copy_cleanup_uint128.sol | 6 +- .../array_copy_clear_storage_packed.sol | 12 ++-- ...ray_copy_storage_storage_static_simple.sol | 4 +- .../copying/array_copy_target_leftover2.sol | 6 +- ...o_storage_dynamic_different_mutability.sol | 2 +- .../copying/arrays_from_and_to_storage.sol | 2 +- .../copying/bytes_storage_to_storage.sol | 4 +- ...sted_array_element_calldata_to_storage.sol | 4 +- ...nested_array_element_memory_to_storage.sol | 4 +- .../delete/delete_storage_array_packed.sol | 6 +- .../array/dynamic_array_cleanup.sol | 6 +- .../array/fixed_array_cleanup.sol | 6 +- .../array/pop/byte_array_pop_copy_long.sol | 6 +- .../array/push/array_push_packed_array.sol | 6 +- .../array/push/push_no_args_2d.sol | 2 +- ...ing_explicit_downcast_during_emissions.sol | 3 +- .../events/event_indexed_mixed.sol | 6 +- .../events/event_signature_in_library.sol | 3 +- .../externalContracts/FixedFeeRegistrar.sol | 6 +- .../externalContracts/prbmath_signed.sol | 58 +++++++++--------- .../externalContracts/prbmath_unsigned.sol | 60 +++++++++---------- .../externalContracts/ramanujan_pi.sol | 4 +- .../externalContracts/strings.sol | 24 ++++---- .../functionCall/send_zero_ether.sol | 6 +- .../functionTypes/store_function.sol | 3 +- .../address_overload_resolution.sol | 6 +- ...d_function_calldata_calldata_interface.sol | 3 +- ...ted_function_calldata_memory_interface.sol | 3 +- .../interface_inheritance_conversions.sol | 10 ++-- .../keccak_yul_optimization.sol | 12 ++-- .../libraries/using_library_structs.sol | 2 +- .../operator_making_pure_external_call.sol | 6 +- .../operator_making_view_external_call.sol | 6 +- .../struct_delete_storage_nested_small.sol | 2 +- ...truct_delete_storage_with_arrays_small.sol | 2 +- .../calldata_to_storage.sol | 18 +++--- .../userDefinedValueType/erc20.sol | 36 +++++------ .../memory_to_storage.sol | 18 +++--- ...cost_abstraction_comparison_elementary.sol | 24 ++++---- ...ost_abstraction_comparison_userdefined.sol | 24 ++++---- .../various/codebalance_assembly.sol | 3 +- .../various/contract_binary_dependencies.sol | 3 +- .../semanticTests/various/erc20.sol | 34 +++++------ 49 files changed, 254 insertions(+), 238 deletions(-) diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 8df4090c3662..78da59648a9d 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -38,6 +38,7 @@ contract C is B { } // ---- // test() -> 5, 10 -// gas irOptimized: 87337 +// gas irOptimized: 65040 +// gas irOptimized code: 26200 // gas legacy: 66250 // gas legacy code: 36400 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index cdce1b95a529..739c4c84076b 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -21,5 +21,5 @@ contract C { // 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: 120978 -// gas legacy: 101568 -// gas legacyOptimized: 119092 +// gas legacy: 98324 +// gas legacyOptimized: 94348 diff --git a/test/libsolidity/semanticTests/array/array_storage_length_access.sol b/test/libsolidity/semanticTests/array/array_storage_length_access.sol index 47fddc5547bc..4f7308c24483 100644 --- a/test/libsolidity/semanticTests/array/array_storage_length_access.sol +++ b/test/libsolidity/semanticTests/array/array_storage_length_access.sol @@ -12,7 +12,7 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 96690 +// gas irOptimized: 98764 // gas legacy: 128571 // gas legacyOptimized: 110143 // set_get_length(uint256): 0xFFF -> 0xFFF diff --git a/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol b/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol index 607e1ecd3547..bf06393a63ff 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol @@ -17,9 +17,9 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0 -> 0 -// gas irOptimized: 77628 -// gas legacy: 77730 -// gas legacyOptimized: 77162 +// gas irOptimized: 76123 +// gas legacy: 75618 +// gas legacyOptimized: 75076 // set_get_length(uint256): 0xFF -> 0xFF // gas irOptimized: 168565 // gas legacy: 696850 diff --git a/test/libsolidity/semanticTests/array/array_storage_push_pop.sol b/test/libsolidity/semanticTests/array/array_storage_push_pop.sol index a4c7d34d7fef..609944ddc086 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_pop.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_pop.sol @@ -13,9 +13,9 @@ contract C { // set_get_length(uint256): 1 -> 0 // set_get_length(uint256): 10 -> 0 // set_get_length(uint256): 20 -> 0 -// gas irOptimized: 106222 -// gas legacy: 105722 -// gas legacyOptimized: 103508 +// gas irOptimized: 87226 +// gas legacy: 85609 +// gas legacyOptimized: 83462 // set_get_length(uint256): 0xFF -> 0 // gas irOptimized: 833586 // gas legacy: 807764 diff --git a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol index 060cafe39a78..68e4b5d62caa 100644 --- a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol +++ b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol @@ -41,15 +41,15 @@ contract c { // ---- // storageEmpty -> 1 // test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710 -// gas legacy: 59838 -// gas legacyOptimized: 58606 +// gas legacy: 57661 +// gas legacyOptimized: 57073 // storageEmpty -> 0 // test_long() -> 67 -// gas irOptimized: 89148 +// gas irOptimized: 89482 // gas legacy: 101607 // gas legacyOptimized: 100479 // storageEmpty -> 0 // test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020 -// gas legacy: 61930 -// gas legacyOptimized: 59404 +// gas legacy: 58079 +// gas legacyOptimized: 56932 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol index 761feebec9d5..e1cfa7ce7e81 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol @@ -21,6 +21,6 @@ contract C { } // ---- // f() -> true -// gas irOptimized: 92740 -// gas legacy: 93035 -// gas legacyOptimized: 92257 +// gas irOptimized: 73992 +// gas legacy: 74395 +// gas legacyOptimized: 73794 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol index 13cb9c28fd26..43827773c196 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol @@ -40,11 +40,11 @@ contract C { } // ---- // f() -> 0 -// gas irOptimized: 92800 -// gas legacy: 93006 -// gas legacyOptimized: 92261 +// gas irOptimized: 74056 +// gas legacy: 74372 +// gas legacyOptimized: 73796 // g() -> 0 // h() -> 0 -// gas irOptimized: 92862 -// gas legacy: 93028 -// gas legacyOptimized: 92303 +// gas irOptimized: 74126 +// gas legacy: 74398 +// gas legacyOptimized: 73833 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol index 2fccff774e94..84642c143901 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol @@ -11,5 +11,5 @@ contract C { } // ---- // test() -> left(0x01), left(0x02) -// gas legacy: 90001 -// gas legacyOptimized: 89085 +// gas legacy: 89698 +// gas legacyOptimized: 88928 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol index 0a2bcffce201..dd49c7a97b6e 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol @@ -19,6 +19,6 @@ contract c { } // ---- // test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0 -// gas irOptimized: 93858 -// gas legacy: 97451 -// gas legacyOptimized: 94200 +// gas irOptimized: 91348 +// gas legacy: 96648 +// gas legacyOptimized: 93841 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol index 2bb3bcf333e3..d121b22d49ea 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol @@ -52,4 +52,4 @@ contract C { // gas legacy: 108295 // gas legacyOptimized: 102162 // copyInternalArrayOfFunctionType() -> true -// gas legacy: 104178 +// gas legacy: 36192 diff --git a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol index af2983b066bd..93b541620ace 100644 --- a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol @@ -10,7 +10,7 @@ contract Test { } // ---- // set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18 -// gas irOptimized: 99616 +// gas irOptimized: 95505 // gas legacy: 103509 // gas legacyOptimized: 101266 // data(uint256): 7 -> 8 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 fe758fe8fd13..d00f5573a0af 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -33,8 +33,8 @@ contract c { // gas legacy: 148692 // gas legacyOptimized: 148699 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 -// gas legacy: 59345 -// gas legacyOptimized: 57279 +// gas legacy: 59751 +// gas legacyOptimized: 57208 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 // gas irOptimized: 416918 // gas legacy: 458997 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol index 5040a72cadb5..89eeb27dcef2 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol @@ -25,5 +25,5 @@ contract C { // ---- // test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 // test2(uint8[2][2]): 1, 2, 3, 4 -// gas irOptimized: 119939 -// gas legacyOptimized: 120228 +// gas irOptimized: 72076 +// gas legacyOptimized: 95103 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol index 2f4b4ca7c9a1..bd74ae0158e2 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol @@ -25,5 +25,5 @@ contract C { // ---- // test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 // test2(uint8[2][2]): 1, 2, 3, 4 -// gas irOptimized: 119939 -// gas legacyOptimized: 120228 +// gas irOptimized: 73031 +// gas legacyOptimized: 96288 diff --git a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol index 9665201c98fd..f486a50cfafe 100644 --- a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol +++ b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol @@ -14,6 +14,6 @@ contract C { } // ---- // f() -> 0, 0, 0 -// gas irOptimized: 90992 -// gas legacy: 111037 -// gas legacyOptimized: 109633 +// gas irOptimized: 88026 +// gas legacy: 88800 +// gas legacyOptimized: 87700 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol index b2be566a9df1..285bc5f6f878 100644 --- a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -19,9 +19,9 @@ contract c { // gas legacyOptimized: 515555 // storageEmpty -> 0 // halfClear() -> -// gas irOptimized: 113961 -// gas legacy: 113257 -// gas legacyOptimized: 113120 +// gas irOptimized: 91472 +// gas legacy: 90567 +// gas legacyOptimized: 90457 // storageEmpty -> 0 // fullClear() -> // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index ebe2186fd60f..b4ba8b47fdba 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -15,7 +15,7 @@ contract c { // gas legacyOptimized: 466238 // storageEmpty -> 0 // clear() -> -// gas irOptimized: 122148 -// gas legacy: 122440 -// gas legacyOptimized: 122259 +// gas irOptimized: 97705 +// gas legacy: 97919 +// gas legacyOptimized: 97790 // storageEmpty -> 1 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 c64d93c1208a..01d2d83f9a44 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 @@ -9,6 +9,6 @@ contract c { } // ---- // test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000 -// gas irOptimized: 109310 -// gas legacy: 101220 -// gas legacyOptimized: 123422 +// gas irOptimized: 85778 +// gas legacy: 97666 +// gas legacyOptimized: 96874 diff --git a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol index e7a3bdbd1f18..e6c010230859 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol @@ -13,6 +13,6 @@ contract c { } // ---- // test() -> 1, 2, 3, 4 -// gas irOptimized: 93017 -// gas legacy: 92798 -// gas legacyOptimized: 92062 +// gas irOptimized: 92545 +// gas legacy: 92756 +// gas legacyOptimized: 92045 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol index 3b35719dbb8d..626c65871ff2 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol @@ -36,7 +36,7 @@ contract C { // f(uint256,uint256): 84, 128 -> // gas irOptimized: 118708 // gas legacy: 109977 -// gas legacyOptimized: 96331 +// gas legacyOptimized: 98446 // l() -> 2 // ll(uint256): 1 -> 85 // a(uint256,uint256): 0, 42 -> 64 diff --git a/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol b/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol index 742c02693df5..08bfac8c273b 100644 --- a/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol +++ b/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol @@ -12,6 +12,7 @@ contract C { // ---- // constructor() -> // ~ emit ev0(bytes1): #"1" -// gas legacy: 168735 +// gas legacy: 58919 +// gas legacy code: 33600 // j() -> // ~ emit ev0(bytes1): #"1" diff --git a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol index ad753ef16fde..66c7f8b5faa4 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol @@ -11,6 +11,6 @@ contract C { // ---- // deposit() -> // ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, "def" -// gas irOptimized: 23709 -// gas legacy: 24342 -// gas legacyOptimized: 23753 +// gas irOptimized: 23695 +// gas legacy: 24328 +// gas legacyOptimized: 23752 diff --git a/test/libsolidity/semanticTests/events/event_signature_in_library.sol b/test/libsolidity/semanticTests/events/event_signature_in_library.sol index d8dc0f15808d..0991cd28a302 100644 --- a/test/libsolidity/semanticTests/events/event_signature_in_library.sol +++ b/test/libsolidity/semanticTests/events/event_signature_in_library.sol @@ -18,4 +18,5 @@ contract C { // ---- // constructor() // ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00 -// gas legacy: 150602 +// gas legacy: 62552 +// gas legacy code: 1600 diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index 47feaf5258bb..e89eeba986fa 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -82,9 +82,9 @@ contract FixedFeeRegistrar is Registrar { // gas legacyOptimized code: 388000 // reserve(string), 69 ether: 0x20, 3, "abc" -> // ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 -// gas irOptimized: 45967 -// gas legacy: 46842 -// gas legacyOptimized: 46091 +// gas irOptimized: 45741 +// gas legacy: 46698 +// gas legacyOptimized: 45948 // owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012 // reserve(string), 70 ether: 0x20, 3, "def" -> // ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol index cb345757f8e1..35e083d5c263 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -55,42 +55,42 @@ contract test { // gas legacyOptimized: 178012 // gas legacyOptimized code: 1669600 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22137 -// gas legacy: 22767 -// gas legacyOptimized: 22282 +// gas irOptimized: 22045 +// gas legacy: 22736 +// gas legacyOptimized: 22264 // exp(int256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 24545 -// gas legacy: 25203 -// gas legacyOptimized: 24357 +// gas irOptimized: 24452 +// gas legacy: 25124 +// gas legacyOptimized: 24351 // exp2(int256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24257 -// gas legacy: 24864 -// gas legacyOptimized: 24110 +// gas irOptimized: 24162 +// gas legacy: 24787 +// gas legacyOptimized: 24105 // gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 22970 -// gas legacy: 23228 -// gas legacyOptimized: 22683 +// gas irOptimized: 22805 +// gas legacy: 23202 +// gas legacyOptimized: 22685 // log10(int256): 3141592653589793238 -> 4971498726941338506 -// gas irOptimized: 30609 -// gas legacy: 32934 -// gas legacyOptimized: 30323 +// gas irOptimized: 30300 +// gas legacy: 32841 +// gas legacyOptimized: 30249 // log2(int256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 28819 -// gas legacy: 31067 -// gas legacyOptimized: 28426 +// gas irOptimized: 28566 +// gas legacy: 30979 +// gas legacyOptimized: 28357 // mul(int256,int256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22225 -// gas legacy: 22807 -// gas legacyOptimized: 22295 +// gas irOptimized: 22147 +// gas legacy: 22775 +// gas legacyOptimized: 22288 // pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22635 -// gas legacy: 23508 +// gas irOptimized: 22488 +// gas legacy: 23453 // gas legacyOptimized: 22921 // sqrt(int256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 22650 -// gas legacy: 22802 -// gas legacyOptimized: 22422 +// gas irOptimized: 22458 +// gas legacy: 22784 +// gas legacyOptimized: 22420 // benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 36630 -// gas legacy: 36673 -// gas legacyOptimized: 34729 +// gas irOptimized: 34893 +// gas legacy: 35244 +// gas legacyOptimized: 33996 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index 5902ba4905b1..38d2a20baa2a 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -55,42 +55,42 @@ contract test { // gas legacyOptimized: 168857 // gas legacyOptimized code: 1556200 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22004 -// gas legacy: 22497 -// gas legacyOptimized: 22010 +// gas irOptimized: 21912 +// gas legacy: 22475 +// gas legacyOptimized: 21998 // exp(uint256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 24444 -// gas legacy: 25104 -// gas legacyOptimized: 24258 +// gas irOptimized: 24334 +// gas legacy: 25026 +// gas legacyOptimized: 24253 // exp2(uint256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24198 -// gas legacy: 24814 -// gas legacyOptimized: 24062 +// gas irOptimized: 24115 +// gas legacy: 24738 +// gas legacyOptimized: 24058 // gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 22950 -// gas legacy: 23269 -// gas legacyOptimized: 22724 +// gas irOptimized: 22786 +// gas legacy: 23244 +// gas legacyOptimized: 22727 // log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a -// gas irOptimized: 30269 -// gas legacy: 32898 -// gas legacyOptimized: 29925 +// gas irOptimized: 30079 +// gas legacy: 32808 +// gas legacyOptimized: 29912 // log2(uint256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 28235 -// gas legacy: 30986 -// gas legacyOptimized: 28001 +// gas irOptimized: 28107 +// gas legacy: 30900 +// gas legacyOptimized: 27994 // mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22048 -// gas legacy: 22604 -// gas legacyOptimized: 22090 +// gas irOptimized: 21988 +// gas legacy: 22581 +// gas legacyOptimized: 22089 // pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22406 -// gas legacy: 23245 -// gas legacyOptimized: 22646 +// gas irOptimized: 22316 +// gas legacy: 23196 +// gas legacyOptimized: 22652 // sqrt(uint256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 22672 -// gas legacy: 22820 -// gas legacyOptimized: 22440 +// gas irOptimized: 22481 +// gas legacy: 22803 +// gas legacyOptimized: 22439 // benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 35603 -// gas legacy: 35385 -// gas legacyOptimized: 33449 +// gas irOptimized: 33961 +// gas legacy: 34006 +// gas legacyOptimized: 32724 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index 70a3004ac4b6..a98e83001a06 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -40,6 +40,6 @@ contract test { // gas legacyOptimized: 82667 // gas legacyOptimized code: 369200 // prb_pi() -> 3141592656369545286 -// gas irOptimized: 57478 +// gas irOptimized: 55036 // gas legacy: 100657 -// gas legacyOptimized: 75735 +// gas legacyOptimized: 74311 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index cb9616bbe40b..8deb86ed517e 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -56,21 +56,21 @@ contract test { // gas legacyOptimized: 102639 // gas legacyOptimized code: 612400 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 -// gas irOptimized: 22660 -// gas legacy: 23190 -// gas legacyOptimized: 22508 +// gas irOptimized: 22646 +// gas legacy: 23168 +// gas legacyOptimized: 22488 // roundtrip(string): 0x20, 11, "hello world" -> 0x20, 11, "hello world" -// gas irOptimized: 23408 -// gas legacy: 23820 -// gas legacyOptimized: 23123 +// gas irOptimized: 23225 +// gas legacy: 23674 +// gas legacyOptimized: 22991 // utf8len(string): 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" -> 4 # Input: "😃😃😃😃" # -// gas irOptimized: 24026 -// gas legacy: 25716 -// gas legacyOptimized: 24115 +// gas irOptimized: 23956 +// gas legacy: 25621 +// gas legacyOptimized: 24096 // multiconcat(string,uint256): 0x40, 3, 11, "hello world" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times # -// gas irOptimized: 28440 -// gas legacy: 31621 -// gas legacyOptimized: 27914 +// gas irOptimized: 27630 +// gas legacy: 30778 +// gas legacyOptimized: 27519 // benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 // gas irOptimized: 1976778 // gas legacy: 4234020 diff --git a/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol b/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol index 94a721323244..8eeaf7b51cad 100644 --- a/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol +++ b/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol @@ -15,8 +15,10 @@ contract Main { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 100264 +// gas irOptimized: 56314 +// gas irOptimized code: 37400 // gas legacy: 57555 // gas legacy code: 53000 -// gas legacyOptimized: 100361 +// gas legacyOptimized: 56463 +// gas legacyOptimized code: 39600 // s() -> true diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index eeab740aa0fb..904bc705f725 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -25,7 +25,8 @@ contract C { } // ---- // t() -> 9 -// gas irOptimized: 99064 +// gas irOptimized: 77300 +// gas irOptimized code: 19000 // gas legacy: 79492 // gas legacy code: 69600 // gas legacyOptimized: 77587 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 90a3f9ec8c1f..f339b52445a4 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -22,10 +22,12 @@ contract D { // EVMVersion: >=constantinople // ---- // f() -> 1 -// gas irOptimized: 77051 +// gas irOptimized: 54014 +// gas irOptimized code: 20200 // gas legacy: 54553 // gas legacy code: 57800 // g() -> 5 -// gas irOptimized: 77106 +// gas irOptimized: 54042 +// gas irOptimized code: 20200 // gas legacy: 55090 // gas legacy code: 57800 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index f64a2e12a10b..e9013d6f52be 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -22,6 +22,7 @@ contract B { } // ---- // g() -> 42 -// gas irOptimized: 80813 +// gas irOptimized: 54536 +// gas irOptimized code: 24800 // gas legacy: 55868 // gas legacy code: 66600 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 07beb2c537d8..36ed3706243a 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -22,7 +22,8 @@ contract B { } // ---- // g() -> 42 -// gas irOptimized: 100282 +// gas irOptimized: 54828 +// gas irOptimized code: 42000 // gas legacy: 56839 // gas legacy code: 123600 // gas legacyOptimized: 55001 diff --git a/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol index 2448b3e03bc2..95f48f60a12f 100644 --- a/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol @@ -29,10 +29,10 @@ contract C is SubA, SubB { } // ---- // convertParent() -> 1 -// gas irOptimized: 85524 +// gas irOptimized: 21793 // convertSubA() -> 1, 2 -// gas irOptimized: 86155 -// gas legacy: 99047 +// gas irOptimized: 22459 +// gas legacy: 23286 // convertSubB() -> 1, 3 -// gas irOptimized: 86098 -// gas legacy: 98981 +// gas irOptimized: 22330 +// gas legacy: 23154 diff --git a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol index 88088bbda84c..e3344bf5d588 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol @@ -24,10 +24,10 @@ contract C { } // ---- // f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 22239 -// gas legacy: 23385 -// gas legacyOptimized: 23092 +// gas irOptimized: 22212 +// gas legacy: 23378 +// gas legacyOptimized: 23089 // g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 21277 -// gas legacy: 21462 -// gas legacyOptimized: 21256 +// gas irOptimized: 21251 +// gas legacy: 21456 +// gas legacyOptimized: 21254 diff --git a/test/libsolidity/semanticTests/libraries/using_library_structs.sol b/test/libsolidity/semanticTests/libraries/using_library_structs.sol index c2ecf1036e88..15398e312d7e 100644 --- a/test/libsolidity/semanticTests/libraries/using_library_structs.sol +++ b/test/libsolidity/semanticTests/libraries/using_library_structs.sol @@ -20,5 +20,5 @@ contract Test { // ---- // library: Lib // f() -> 7, 8 -// gas irOptimized: 101818 +// gas irOptimized: 97577 // gas legacy: 101428 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol index 364e589e55c1..b901cab0351a 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol @@ -54,13 +54,15 @@ contract C { // EVMVersion: >=constantinople // ---- // testMul(int32,int32): 42, 10 -> 420 -// gas irOptimized: 102563 +// gas irOptimized: 54784 +// gas irOptimized code: 40600 // gas legacy: 57117 // gas legacy code: 127000 // gas legacyOptimized: 55246 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 -// gas irOptimized: 102386 +// gas irOptimized: 54621 +// gas irOptimized code: 40600 // gas legacy: 56378 // gas legacy code: 127000 // gas legacyOptimized: 54943 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol index 54048113c323..15501b3fc24e 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol @@ -60,13 +60,15 @@ contract C { // EVMVersion: >=constantinople // ---- // testMul(int32,int32): 42, 10 -> 420 -// gas irOptimized: 102563 +// gas irOptimized: 54784 +// gas irOptimized code: 40600 // gas legacy: 57117 // gas legacy code: 127000 // gas legacyOptimized: 55246 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 -// gas irOptimized: 102386 +// gas irOptimized: 54621 +// gas irOptimized code: 40600 // gas legacy: 56378 // gas legacy code: 127000 // gas legacyOptimized: 54943 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol index 57bf38e52c6b..a8e29dcad8ee 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol @@ -33,4 +33,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0, 0, 0 -// gas irOptimized: 117101 +// gas irOptimized: 93830 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol index 2345fea3cfe2..871c614f5621 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol @@ -27,4 +27,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0 -// gas irOptimized: 111570 +// gas irOptimized: 89435 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol index c3d58811ae4e..292b9fbfe352 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol @@ -23,19 +23,19 @@ contract C { // ---- // s() -> 0, 0, 0x00, 0 // f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> -// gas irOptimized: 44405 -// gas legacy: 47200 -// gas legacyOptimized: 44923 +// gas irOptimized: 44237 +// gas legacy: 47154 +// gas legacyOptimized: 45018 // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 -// gas irOptimized: 69097 -// gas legacy: 75466 -// gas legacyOptimized: 74255 +// gas irOptimized: 68578 +// gas legacy: 75429 +// gas legacyOptimized: 74244 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" -// gas irOptimized: 69174 -// gas legacy: 75156 -// gas legacyOptimized: 74342 +// gas irOptimized: 68635 +// gas legacy: 75125 +// gas legacyOptimized: 74331 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 // l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index 0e0759d62aa1..acd9ea840895 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -120,29 +120,29 @@ contract ERC20 { // gas legacyOptimized: 127464 // gas legacyOptimized code: 285400 // totalSupply() -> 20 -// gas irOptimized: 23415 -// gas legacy: 23653 -// gas legacyOptimized: 23368 +// gas irOptimized: 23334 +// gas legacy: 23645 +// gas legacyOptimized: 23367 // transfer(address,uint256): 2, 5 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 -// gas irOptimized: 48471 -// gas legacy: 49572 -// gas legacyOptimized: 48575 +// gas irOptimized: 50997 +// gas legacy: 52323 +// gas legacyOptimized: 51380 // decreaseAllowance(address,uint256): 2, 0 -> true // ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 -// gas irOptimized: 26275 -// gas legacy: 27204 -// gas legacyOptimized: 26317 +// gas irOptimized: 26054 +// gas legacy: 27165 +// gas legacyOptimized: 26320 // decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24042 -// gas legacy: 24506 -// gas legacyOptimized: 24077 +// gas irOptimized: 23954 +// gas legacy: 24500 +// gas legacyOptimized: 24076 // transfer(address,uint256): 2, 14 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e -// gas irOptimized: 28571 -// gas legacy: 29672 -// gas legacyOptimized: 28675 +// gas irOptimized: 33897 +// gas legacy: 35223 +// gas legacyOptimized: 34280 // transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24071 -// gas legacy: 24492 -// gas legacyOptimized: 24074 +// gas irOptimized: 23990 +// gas legacy: 24483 +// gas legacyOptimized: 24072 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol index db745dce31ec..585249f2f539 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol @@ -23,19 +23,19 @@ contract C { // ---- // s() -> 0, 0, 0x00, 0 // f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> -// gas irOptimized: 44473 -// gas legacy: 46213 -// gas legacyOptimized: 44671 +// gas irOptimized: 44360 +// gas legacy: 46189 +// gas legacyOptimized: 44673 // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 -// gas irOptimized: 69555 -// gas legacy: 76557 -// gas legacyOptimized: 74834 +// gas irOptimized: 68898 +// gas legacy: 76511 +// gas legacyOptimized: 74832 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" -// gas irOptimized: 69617 -// gas legacy: 76238 -// gas legacyOptimized: 74921 +// gas irOptimized: 68937 +// gas legacy: 76198 +// gas legacyOptimized: 74919 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 // l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol index 2c5a15bb93ac..c254d9abdd9d 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol @@ -17,18 +17,18 @@ contract C { } // ---- // getX() -> 0 -// gas irOptimized: 23379 -// gas legacy: 23479 -// gas legacyOptimized: 23311 +// gas irOptimized: 23311 +// gas legacy: 23473 +// gas legacyOptimized: 23309 // setX(int256): 5 -> -// gas irOptimized: 43510 -// gas legacy: 43724 -// gas legacyOptimized: 43516 +// gas irOptimized: 43464 +// gas legacy: 43718 +// gas legacyOptimized: 43513 // getX() -> 5 -// gas irOptimized: 23379 -// gas legacy: 23479 -// gas legacyOptimized: 23311 +// gas irOptimized: 23311 +// gas legacy: 23473 +// gas legacyOptimized: 23309 // add(int256,int256): 200, 99 -> 299 -// gas irOptimized: 21764 -// gas legacy: 22394 -// gas legacyOptimized: 21813 +// gas irOptimized: 21623 +// gas legacy: 22354 +// gas legacyOptimized: 21768 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol index 2f275c543b11..89f811862f40 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol @@ -18,18 +18,18 @@ contract C { } // ---- // getX() -> 0 -// gas irOptimized: 23379 -// gas legacy: 23608 -// gas legacyOptimized: 23311 +// gas irOptimized: 23311 +// gas legacy: 23599 +// gas legacyOptimized: 23309 // setX(int256): 5 -> -// gas irOptimized: 43510 -// gas legacy: 43724 -// gas legacyOptimized: 43516 +// gas irOptimized: 43464 +// gas legacy: 43718 +// gas legacyOptimized: 43513 // getX() -> 5 -// gas irOptimized: 23379 -// gas legacy: 23608 -// gas legacyOptimized: 23311 +// gas irOptimized: 23311 +// gas legacy: 23599 +// gas legacyOptimized: 23309 // add(int256,int256): 200, 99 -> 299 -// gas irOptimized: 21764 -// gas legacy: 22523 -// gas legacyOptimized: 21813 +// gas irOptimized: 21623 +// gas legacy: 22480 +// gas legacyOptimized: 21768 diff --git a/test/libsolidity/semanticTests/various/codebalance_assembly.sol b/test/libsolidity/semanticTests/various/codebalance_assembly.sol index fad0d3e5b465..6faffd639965 100644 --- a/test/libsolidity/semanticTests/various/codebalance_assembly.sol +++ b/test/libsolidity/semanticTests/various/codebalance_assembly.sol @@ -21,7 +21,8 @@ contract C { // EVMVersion: >=constantinople // ---- // constructor(), 23 wei -> -// gas legacy: 100517 +// gas legacy: 56667 +// gas legacy code: 42000 // f() -> 0 // g() -> 1 // h() -> 23 diff --git a/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol b/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol index 0ebf772fbad7..d1fae4b7fa72 100644 --- a/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol +++ b/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol @@ -17,4 +17,5 @@ contract C { } // ---- // constructor() -> -// gas irOptimized: 100415 +// gas irOptimized: 56611 +// gas irOptimized code: 39400 diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index 1cc77270f67b..13b914d9b80b 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -103,29 +103,29 @@ contract ERC20 { // gas legacyOptimized: 126934 // gas legacyOptimized code: 282000 // totalSupply() -> 20 -// gas irOptimized: 23415 -// gas legacy: 23524 -// gas legacyOptimized: 23368 +// gas irOptimized: 23334 +// gas legacy: 23519 +// gas legacyOptimized: 23367 // transfer(address,uint256): 2, 5 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 -// gas irOptimized: 48471 -// gas legacy: 49317 -// gas legacyOptimized: 48491 +// gas irOptimized: 51054 +// gas legacy: 52073 +// gas legacyOptimized: 51298 // decreaseAllowance(address,uint256): 2, 0 -> true // ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 -// gas irOptimized: 26275 -// gas legacy: 27012 -// gas legacyOptimized: 26275 +// gas irOptimized: 26087 +// gas legacy: 26977 +// gas legacyOptimized: 26279 // decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24042 -// gas legacy: 24467 +// gas irOptimized: 23981 +// gas legacy: 24462 // gas legacyOptimized: 24056 // transfer(address,uint256): 2, 14 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e -// gas irOptimized: 28571 -// gas legacy: 29417 -// gas legacyOptimized: 28591 +// gas irOptimized: 33954 +// gas legacy: 34973 +// gas legacyOptimized: 34198 // transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24071 -// gas legacy: 24453 -// gas legacyOptimized: 24053 +// gas irOptimized: 24020 +// gas legacy: 24445 +// gas legacyOptimized: 24052 From da092b5b2640b74df6ed20aa404e3e3f4eddff4e Mon Sep 17 00:00:00 2001 From: Marco Castignoli Date: Tue, 16 Dec 2025 17:00:02 +0100 Subject: [PATCH 16/33] Move constantinople and petersburg runs to nightly --- .circleci/config.yml | 2 +- .circleci/soltest_all.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 69ae1999fc3e..3cab7fbadb58 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1328,7 +1328,7 @@ jobs: - attach_workspace: at: build - run_soltest_all: - evm_versions: homestead byzantium + evm_versions: homestead byzantium constantinople petersburg - store_test_results: path: test_results/ - store_artifacts_test_results diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 8d6fc486b899..effbc33da0da 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -31,7 +31,7 @@ REPODIR="$(realpath "$(dirname "$0")"/..)" # shellcheck source=scripts/common.sh source "${REPODIR}/scripts/common.sh" -DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun prague osaka) +DEFAULT_EVM_VALUES=(istanbul berlin london paris shanghai cancun prague osaka) EVMS_WITH_EOF=(osaka) # Deserialize the EVM_VALUES array if it was provided as argument or From eaaba5f4a581605d0ecdf52c910792ccc5f6aa90 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 8 Dec 2025 17:17:00 +0100 Subject: [PATCH 17/33] Apply fix --- libsolidity/codegen/ExpressionCompiler.cpp | 1 + libsolidity/codegen/ir/IRGeneratorForStatements.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 85634906e01f..2927444e2be3 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -2133,6 +2133,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) dynamic_cast(_memberAccess.annotation().referencedDeclaration) || dynamic_cast(_memberAccess.annotation().referencedDeclaration) || dynamic_cast(_memberAccess.annotation().referencedDeclaration) || + dynamic_cast(_memberAccess.annotation().referencedDeclaration) || category == Type::Category::TypeType || category == Type::Category::Module, "" diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 5902cfef68b6..66736da5f4c5 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2252,6 +2252,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) dynamic_cast(_memberAccess.annotation().referencedDeclaration) || dynamic_cast(_memberAccess.annotation().referencedDeclaration) || dynamic_cast(_memberAccess.annotation().referencedDeclaration) || + dynamic_cast(_memberAccess.annotation().referencedDeclaration) || category == Type::Category::TypeType || category == Type::Category::Module, "" From 910350b0609a5df76bf26807da840dcbe675d704 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 8 Dec 2025 17:17:09 +0100 Subject: [PATCH 18/33] Add tests --- ...t_event_from_module_via_member_access.json | 1046 +++++++++++++++++ ...it_event_from_module_via_member_access.sol | 18 + .../error_from_module_via_member_access.json | 544 +++++++++ .../error_from_module_via_member_access.sol | 22 + ...it_event_from_module_via_member_access.sol | 115 ++ .../error_from_module_via_member_access.sol | 127 ++ ...or_throw_from_module_via_member_access.sol | 31 + ...ent_emit_from_module_via_member_access.sol | 26 + 8 files changed, 1929 insertions(+) create mode 100644 test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.json create mode 100644 test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.sol create mode 100644 test/libsolidity/ASTJSON/error_from_module_via_member_access.json create mode 100644 test/libsolidity/ASTJSON/error_from_module_via_member_access.sol create mode 100644 test/libsolidity/natspecJSON/emit_event_from_module_via_member_access.sol create mode 100644 test/libsolidity/natspecJSON/error_from_module_via_member_access.sol create mode 100644 test/libsolidity/semanticTests/errors/error_throw_from_module_via_member_access.sol create mode 100644 test/libsolidity/semanticTests/events/event_emit_from_module_via_member_access.sol diff --git a/test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.json b/test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.json new file mode 100644 index 000000000000..a33847450bc2 --- /dev/null +++ b/test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.json @@ -0,0 +1,1046 @@ +[ +{ + "absolutePath": "A.sol", + "exportedSymbols": { + "AContract": [ + 17 + ], + "TransferA": [ + 8 + ] + }, + "id": 18, + "nodeType": "SourceUnit", + "nodes": [ + { + "anonymous": false, + "eventSelector": "ef0684aa87ada311bea2dad2b653ce28cd604aa1c10a123df8fb2f789c3178f0", + "id": 8, + "name": "TransferA", + "nameLocation": "6:9:1", + "nodeType": "EventDefinition", + "parameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2, + "indexed": true, + "mutability": "mutable", + "name": "from", + "nameLocation": "32:4:1", + "nodeType": "VariableDeclaration", + "scope": 8, + "src": "16:20:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "16:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 4, + "indexed": true, + "mutability": "mutable", + "name": "to", + "nameLocation": "54:2:1", + "nodeType": "VariableDeclaration", + "scope": 8, + "src": "38:18:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 3, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "38:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 6, + "indexed": false, + "mutability": "mutable", + "name": "amount", + "nameLocation": "63:6:1", + "nodeType": "VariableDeclaration", + "scope": 8, + "src": "58:11:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 5, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "58:4:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "15:55:1" + }, + "src": "0:71:1" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "AContract", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 17, + "linearizedBaseContracts": [ + 17 + ], + "name": "AContract", + "nameLocation": "81:9:1", + "nodeType": "ContractDefinition", + "nodes": [ + { + "anonymous": false, + "eventSelector": "665f5beb8eab22c2d0fba9f14e33a83ad719ffbed2f484458c23490e8577adc9", + "id": 16, + "name": "TransferAContract", + "nameLocation": "103:17:1", + "nodeType": "EventDefinition", + "parameters": { + "id": 15, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 10, + "indexed": true, + "mutability": "mutable", + "name": "from", + "nameLocation": "137:4:1", + "nodeType": "VariableDeclaration", + "scope": 16, + "src": "121:20:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 9, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "121:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 12, + "indexed": true, + "mutability": "mutable", + "name": "to", + "nameLocation": "159:2:1", + "nodeType": "VariableDeclaration", + "scope": 16, + "src": "143:18:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 11, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "143:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 14, + "indexed": false, + "mutability": "mutable", + "name": "amount", + "nameLocation": "168:6:1", + "nodeType": "VariableDeclaration", + "scope": 16, + "src": "163:11:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 13, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "163:4:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "120:55:1" + }, + "src": "97:79:1" + } + ], + "scope": 18, + "src": "72:106:1", + "usedErrors": [], + "usedEvents": [ + 16 + ] + } + ], + "src": "0:179:1" +}, +{ + "absolutePath": "ERC20.sol", + "exportedSymbols": { + "A": [ + 19 + ], + "ERC20": [ + 74 + ] + }, + "id": 75, + "nodeType": "SourceUnit", + "nodes": [ + { + "absolutePath": "A.sol", + "file": "A.sol", + "id": 19, + "nameLocation": "12:1:2", + "nodeType": "ImportDirective", + "scope": 75, + "sourceUnit": 18, + "src": "0:27:2", + "symbolAliases": [], + "unitAlias": "A" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ERC20", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 74, + "linearizedBaseContracts": [ + 74 + ], + "name": "ERC20", + "nameLocation": "37:5:2", + "nodeType": "ContractDefinition", + "nodes": [ + { + "anonymous": false, + "eventSelector": "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "id": 27, + "name": "Transfer", + "nameLocation": "55:8:2", + "nodeType": "EventDefinition", + "parameters": { + "id": 26, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21, + "indexed": true, + "mutability": "mutable", + "name": "from", + "nameLocation": "80:4:2", + "nodeType": "VariableDeclaration", + "scope": 27, + "src": "64:20:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "64:7:2", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 23, + "indexed": true, + "mutability": "mutable", + "name": "to", + "nameLocation": "102:2:2", + "nodeType": "VariableDeclaration", + "scope": 27, + "src": "86:18:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "86:7:2", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 25, + "indexed": false, + "mutability": "mutable", + "name": "amount", + "nameLocation": "111:6:2", + "nodeType": "VariableDeclaration", + "scope": 27, + "src": "106:11:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 24, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "106:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "63:55:2" + }, + "src": "49:70:2" + }, + { + "body": { + "id": 72, + "nodeType": "Block", + "src": "145:181:2", + "statements": [ + { + "eventCall": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "31", + "id": 33, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "177:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "id": 32, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "169:7:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 31, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "169:7:2", + "typeDescriptions": {} + } + }, + "id": 34, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "169:10:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "hexValue": "32", + "id": 37, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "189:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "id": 36, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "181:7:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 35, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "181:7:2", + "typeDescriptions": {} + } + }, + "id": 38, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "181:10:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "hexValue": "33", + "id": 39, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "193:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + } + ], + "id": 30, + "name": "Transfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 27, + "src": "160:8:2", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 40, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "160:35:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 41, + "nodeType": "EmitStatement", + "src": "155:40:2" + }, + { + "eventCall": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "31", + "id": 47, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "230:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "id": 46, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "222:7:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 45, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "222:7:2", + "typeDescriptions": {} + } + }, + "id": 48, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "222:10:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "hexValue": "32", + "id": 51, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "242:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "id": 50, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "234:7:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 49, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "234:7:2", + "typeDescriptions": {} + } + }, + "id": 52, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "234:10:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "hexValue": "33", + "id": 53, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "246:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + } + ], + "expression": { + "id": 42, + "name": "A", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 19, + "src": "210:1:2", + "typeDescriptions": { + "typeIdentifier": "t_module_18", + "typeString": "module \"A.sol\"" + } + }, + "id": 44, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "212:9:2", + "memberName": "TransferA", + "nodeType": "MemberAccess", + "referencedDeclaration": 8, + "src": "210:11:2", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 54, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "210:38:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 55, + "nodeType": "EmitStatement", + "src": "205:43:2" + }, + { + "eventCall": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "31", + "id": 63, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "301:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "id": 62, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "293:7:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 61, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "293:7:2", + "typeDescriptions": {} + } + }, + "id": 64, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "293:10:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "hexValue": "32", + "id": 67, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "313:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "id": 66, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "305:7:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 65, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "305:7:2", + "typeDescriptions": {} + } + }, + "id": 68, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "305:10:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "hexValue": "33", + "id": 69, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "317:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + } + ], + "expression": { + "expression": { + "id": 56, + "name": "A", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 19, + "src": "263:1:2", + "typeDescriptions": { + "typeIdentifier": "t_module_18", + "typeString": "module \"A.sol\"" + } + }, + "id": 59, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "265:9:2", + "memberName": "AContract", + "nodeType": "MemberAccess", + "referencedDeclaration": 17, + "src": "263:11:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_AContract_$17_$", + "typeString": "type(contract AContract)" + } + }, + "id": 60, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "275:17:2", + "memberName": "TransferAContract", + "nodeType": "MemberAccess", + "referencedDeclaration": 16, + "src": "263:29:2", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 70, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "263:56:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 71, + "nodeType": "EmitStatement", + "src": "258:61:2" + } + ] + }, + "functionSelector": "26121ff0", + "id": 73, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "133:1:2", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 28, + "nodeType": "ParameterList", + "parameters": [], + "src": "135:2:2" + }, + "returnParameters": { + "id": 29, + "nodeType": "ParameterList", + "parameters": [], + "src": "145:0:2" + }, + "scope": 74, + "src": "124:202:2", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 75, + "src": "28:300:2", + "usedErrors": [], + "usedEvents": [ + 8, + 16, + 27 + ] + } + ], + "src": "0:329:2" +} +] diff --git a/test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.sol b/test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.sol new file mode 100644 index 000000000000..fa9614e21400 --- /dev/null +++ b/test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.sol @@ -0,0 +1,18 @@ +==== Source: A.sol ==== +event TransferA(address indexed from, address indexed to, uint amount); +contract AContract { + event TransferAContract(address indexed from, address indexed to, uint amount); +} + +==== Source: ERC20.sol ==== +import * as A from "A.sol"; +contract ERC20 { + event Transfer(address indexed from, address indexed to, uint amount); + function f () public { + emit Transfer(address(1), address(2), 3); + emit A.TransferA(address(1), address(2), 3); + emit A.AContract.TransferAContract(address(1), address(2), 3); + } +} + +// ---- diff --git a/test/libsolidity/ASTJSON/error_from_module_via_member_access.json b/test/libsolidity/ASTJSON/error_from_module_via_member_access.json new file mode 100644 index 000000000000..db9062891a9b --- /dev/null +++ b/test/libsolidity/ASTJSON/error_from_module_via_member_access.json @@ -0,0 +1,544 @@ +[ +{ + "absolutePath": "A.sol", + "exportedSymbols": { + "AContract": [ + 9 + ], + "ErrorA": [ + 4 + ] + }, + "id": 10, + "nodeType": "SourceUnit", + "nodes": [ + { + "errorSelector": "23b0db14", + "id": 4, + "name": "ErrorA", + "nameLocation": "6:6:1", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 3, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "msg", + "nameLocation": "20:3:1", + "nodeType": "VariableDeclaration", + "scope": 4, + "src": "13:10:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 1, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "13:6:1", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "src": "12:12:1" + }, + "src": "0:25:1" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "AContract", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 9, + "linearizedBaseContracts": [ + 9 + ], + "name": "AContract", + "nameLocation": "35:9:1", + "nodeType": "ContractDefinition", + "nodes": [ + { + "errorSelector": "e00f4941", + "id": 8, + "name": "ErrorAContract", + "nameLocation": "57:14:1", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "msg", + "nameLocation": "79:3:1", + "nodeType": "VariableDeclaration", + "scope": 8, + "src": "72:10:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 5, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "72:6:1", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "src": "71:12:1" + }, + "src": "51:33:1" + } + ], + "scope": 10, + "src": "26:60:1", + "usedErrors": [ + 8 + ], + "usedEvents": [] + } + ], + "src": "0:87:1" +}, +{ + "absolutePath": "B.sol", + "exportedSymbols": { + "A": [ + 11 + ], + "BContract": [ + 46 + ] + }, + "id": 47, + "nodeType": "SourceUnit", + "nodes": [ + { + "absolutePath": "A.sol", + "file": "A.sol", + "id": 11, + "nameLocation": "12:1:2", + "nodeType": "ImportDirective", + "scope": 47, + "sourceUnit": 10, + "src": "0:27:2", + "symbolAliases": [], + "unitAlias": "A" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "BContract", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 46, + "linearizedBaseContracts": [ + 46 + ], + "name": "BContract", + "nameLocation": "37:9:2", + "nodeType": "ContractDefinition", + "nodes": [ + { + "errorSelector": "1e012d26", + "id": 15, + "name": "ErrorBContract", + "nameLocation": "59:14:2", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 14, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 13, + "mutability": "mutable", + "name": "msg", + "nameLocation": "81:3:2", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "74:10:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 12, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "74:6:2", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "src": "73:12:2" + }, + "src": "53:33:2" + }, + { + "body": { + "id": 22, + "nodeType": "Block", + "src": "113:52:2", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "hexValue": "736f6d65206572726f72", + "id": 19, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "145:12:2", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577", + "typeString": "literal_string \"some error\"" + }, + "value": "some error" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577", + "typeString": "literal_string \"some error\"" + } + ], + "id": 18, + "name": "ErrorBContract", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 15, + "src": "130:14:2", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_string_memory_ptr_$returns$_t_error_$", + "typeString": "function (string memory) pure returns (error)" + } + }, + "id": 20, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "130:28:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_error", + "typeString": "error" + } + }, + "id": 21, + "nodeType": "RevertStatement", + "src": "123:35:2" + } + ] + }, + "functionSelector": "c27fc305", + "id": 23, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f1", + "nameLocation": "100:2:2", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 16, + "nodeType": "ParameterList", + "parameters": [], + "src": "103:2:2" + }, + "returnParameters": { + "id": 17, + "nodeType": "ParameterList", + "parameters": [], + "src": "113:0:2" + }, + "scope": 46, + "src": "91:74:2", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": { + "id": 32, + "nodeType": "Block", + "src": "192:46:2", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "hexValue": "736f6d65206572726f72", + "id": 29, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "218:12:2", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577", + "typeString": "literal_string \"some error\"" + }, + "value": "some error" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577", + "typeString": "literal_string \"some error\"" + } + ], + "expression": { + "id": 26, + "name": "A", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 11, + "src": "209:1:2", + "typeDescriptions": { + "typeIdentifier": "t_module_10", + "typeString": "module \"A.sol\"" + } + }, + "id": 28, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "211:6:2", + "memberName": "ErrorA", + "nodeType": "MemberAccess", + "referencedDeclaration": 4, + "src": "209:8:2", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_string_memory_ptr_$returns$_t_error_$", + "typeString": "function (string memory) pure returns (error)" + } + }, + "id": 30, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "209:22:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_error", + "typeString": "error" + } + }, + "id": 31, + "nodeType": "RevertStatement", + "src": "202:29:2" + } + ] + }, + "functionSelector": "9942ec6f", + "id": 33, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f2", + "nameLocation": "179:2:2", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "182:2:2" + }, + "returnParameters": { + "id": 25, + "nodeType": "ParameterList", + "parameters": [], + "src": "192:0:2" + }, + "scope": 46, + "src": "170:68:2", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": { + "id": 44, + "nodeType": "Block", + "src": "265:64:2", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "hexValue": "736f6d65206572726f72", + "id": 41, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "309:12:2", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577", + "typeString": "literal_string \"some error\"" + }, + "value": "some error" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577", + "typeString": "literal_string \"some error\"" + } + ], + "expression": { + "expression": { + "id": 36, + "name": "A", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 11, + "src": "282:1:2", + "typeDescriptions": { + "typeIdentifier": "t_module_10", + "typeString": "module \"A.sol\"" + } + }, + "id": 39, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "284:9:2", + "memberName": "AContract", + "nodeType": "MemberAccess", + "referencedDeclaration": 9, + "src": "282:11:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_AContract_$9_$", + "typeString": "type(contract AContract)" + } + }, + "id": 40, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "294:14:2", + "memberName": "ErrorAContract", + "nodeType": "MemberAccess", + "referencedDeclaration": 8, + "src": "282:26:2", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_string_memory_ptr_$returns$_t_error_$", + "typeString": "function (string memory) pure returns (error)" + } + }, + "id": 42, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "282:40:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_error", + "typeString": "error" + } + }, + "id": 43, + "nodeType": "RevertStatement", + "src": "275:47:2" + } + ] + }, + "functionSelector": "aaf05f3d", + "id": 45, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f3", + "nameLocation": "252:2:2", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 34, + "nodeType": "ParameterList", + "parameters": [], + "src": "255:2:2" + }, + "returnParameters": { + "id": 35, + "nodeType": "ParameterList", + "parameters": [], + "src": "265:0:2" + }, + "scope": 46, + "src": "243:86:2", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 47, + "src": "28:303:2", + "usedErrors": [ + 4, + 8, + 15 + ], + "usedEvents": [] + } + ], + "src": "0:332:2" +} +] diff --git a/test/libsolidity/ASTJSON/error_from_module_via_member_access.sol b/test/libsolidity/ASTJSON/error_from_module_via_member_access.sol new file mode 100644 index 000000000000..74c29fabb29f --- /dev/null +++ b/test/libsolidity/ASTJSON/error_from_module_via_member_access.sol @@ -0,0 +1,22 @@ +==== Source: A.sol ==== +error ErrorA(string msg); +contract AContract { + error ErrorAContract(string msg); +} + +==== Source: B.sol ==== +import * as A from "A.sol"; +contract BContract { + error ErrorBContract(string msg); + function f1 () public { + revert ErrorBContract("some error"); + } + function f2 () public { + revert A.ErrorA("some error"); + } + function f3 () public { + revert A.AContract.ErrorAContract("some error"); + } +} + +// ---- diff --git a/test/libsolidity/natspecJSON/emit_event_from_module_via_member_access.sol b/test/libsolidity/natspecJSON/emit_event_from_module_via_member_access.sol new file mode 100644 index 000000000000..39d1644fe581 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_event_from_module_via_member_access.sol @@ -0,0 +1,115 @@ +==== Source: A.sol ==== +/// @notice This event is emitted when a transfer from A occurs. +/// @param from The source account. +/// @param to The destination account. +/// @param amount The amount. +/// @dev A test case! +event TransferA(address indexed from, address indexed to, uint amount); + +contract AContract { + /// @notice This event is emitted when a transfer from AContract occurs. + /// @param from The source account. + /// @param to The destination account. + /// @param amount The amount. + /// @dev A test case! + event TransferAContract(address indexed from, address indexed to, uint amount); +} + +==== Source: ERC20.sol ==== +import * as A from "A.sol"; +contract ERC20 { + /// @notice This event is emitted when a transfer from ERC20 occurs. + /// @param from The source account. + /// @param to The destination account. + /// @param amount The amount. + /// @dev A test case! + event Transfer(address indexed from, address indexed to, uint amount); + + function test() public { + emit Transfer(address(1), address(5), 1); + emit A.AContract.TransferAContract(address(1), address(5), 1); + emit A.TransferA(address(1), address(5), 1); + } +} + +// ---- +// ---- +// A.sol:AContract devdoc +// { +// "events": { +// "TransferAContract(address,address,uint256)": { +// "details": "A test case!", +// "params": { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// A.sol:AContract userdoc +// { +// "events": { +// "TransferAContract(address,address,uint256)": { +// "notice": "This event is emitted when a transfer from AContract occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// ERC20.sol:ERC20 devdoc +// { +// "events": { +// "Transfer(address,address,uint256)": { +// "details": "A test case!", +// "params": { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// }, +// "TransferA(address,address,uint256)": { +// "details": "A test case!", +// "params": { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// }, +// "TransferAContract(address,address,uint256)": { +// "details": "A test case!", +// "params": { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// ERC20.sol:ERC20 userdoc +// { +// "events": { +// "Transfer(address,address,uint256)": { +// "notice": "This event is emitted when a transfer from ERC20 occurs." +// }, +// "TransferA(address,address,uint256)": { +// "notice": "This event is emitted when a transfer from A occurs." +// }, +// "TransferAContract(address,address,uint256)": { +// "notice": "This event is emitted when a transfer from AContract occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/error_from_module_via_member_access.sol b/test/libsolidity/natspecJSON/error_from_module_via_member_access.sol new file mode 100644 index 000000000000..0c2e44e3cee7 --- /dev/null +++ b/test/libsolidity/natspecJSON/error_from_module_via_member_access.sol @@ -0,0 +1,127 @@ +==== Source: A.sol ==== +/// Something failed. +/// @dev an error. +/// @param a first parameter +/// @param b second parameter +error E(uint a, uint b); + +contract AContract { + /// Something failed. + /// @dev an error. + /// @param a first parameter + /// @param b second parameter + error EAContract(uint a, uint b); +} + +==== Source: ERC20.sol ==== +import * as A from "A.sol"; +contract ERC20 { + /// Something failed. + /// @dev an error. + /// @param a first parameter + /// @param b second parameter + error EERC20(uint a, uint b); + + function f(uint a) public pure { + if (a > 0) + revert EERC20(1, 2); + else if (a < 0) + revert A.AContract.EAContract(5, 6); + else + revert A.E(5, 6); + } +} + +// ---- +// ---- +// A.sol:AContract devdoc +// { +// "errors": { +// "EAContract(uint256,uint256)": [ +// { +// "details": "an error.", +// "params": { +// "a": "first parameter", +// "b": "second parameter" +// } +// } +// ] +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// A.sol:AContract userdoc +// { +// "errors": { +// "EAContract(uint256,uint256)": [ +// { +// "notice": "Something failed." +// } +// ] +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// ERC20.sol:ERC20 devdoc +// { +// "errors": { +// "E(uint256,uint256)": [ +// { +// "details": "an error.", +// "params": { +// "a": "first parameter", +// "b": "second parameter" +// } +// } +// ], +// "EAContract(uint256,uint256)": [ +// { +// "details": "an error.", +// "params": { +// "a": "first parameter", +// "b": "second parameter" +// } +// } +// ], +// "EERC20(uint256,uint256)": [ +// { +// "details": "an error.", +// "params": { +// "a": "first parameter", +// "b": "second parameter" +// } +// } +// ] +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// ERC20.sol:ERC20 userdoc +// { +// "errors": { +// "E(uint256,uint256)": [ +// { +// "notice": "Something failed." +// } +// ], +// "EAContract(uint256,uint256)": [ +// { +// "notice": "Something failed." +// } +// ], +// "EERC20(uint256,uint256)": [ +// { +// "notice": "Something failed." +// } +// ] +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/semanticTests/errors/error_throw_from_module_via_member_access.sol b/test/libsolidity/semanticTests/errors/error_throw_from_module_via_member_access.sol new file mode 100644 index 000000000000..f9b968694aa4 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/error_throw_from_module_via_member_access.sol @@ -0,0 +1,31 @@ +==== Source: A.sol ==== +error ErrorA(string msg); +==== Source: B.sol ==== +import * as A from "A.sol"; + +error ErrorB(string msg); + +contract BContract { + error ErrorB(string msg); +} +==== Source: C.sol ==== +import * as B from "B.sol"; + +contract CContract { + function error1() external { + revert B.ErrorB("B error"); + } + + function error2() external { + revert B.BContract.ErrorB("B.BContract error"); + } + + function error3() external { + revert B.A.ErrorA("B.A error"); + } +} + +// ---- +// error1() -> FAILURE, hex"a5f9ec67", 0x20, 7, "B error" +// error2() -> FAILURE, hex"a5f9ec67", 0x20, 17, "B.BContract error" +// error3() -> FAILURE, hex"23b0db14", 0x20, 9, "B.A error" diff --git a/test/libsolidity/semanticTests/events/event_emit_from_module_via_member_access.sol b/test/libsolidity/semanticTests/events/event_emit_from_module_via_member_access.sol new file mode 100644 index 000000000000..b944ea1148a7 --- /dev/null +++ b/test/libsolidity/semanticTests/events/event_emit_from_module_via_member_access.sol @@ -0,0 +1,26 @@ +==== Source: A.sol ==== +event Transfer(address indexed _from, address indexed _to, uint256 _value); +==== Source: B.sol ==== +import * as A from "A.sol"; + +event Transfer(address indexed _from, address indexed _to, uint256 _value); + +contract BContract { + event Transfer(address indexed _from, address indexed _to, uint256 _value); +} +==== Source: C.sol ==== +import * as B from "B.sol"; + +contract CContract { + function returnAddress() external { + emit B.Transfer(address(0x0b), address(0x0c), 0x0d); + emit B.BContract.Transfer(address(0x0e), address(0x0f), 0x10); + emit B.A.Transfer(address(0x11), address(0x12), 0x13); + } +} + +// ---- +// returnAddress() -> +// ~ emit Transfer(address,address,uint256): #0x0b, #0x0c, 0x0d +// ~ emit Transfer(address,address,uint256): #0x0e, #0x0f, 0x10 +// ~ emit Transfer(address,address,uint256): #0x11, #0x12, 0x13 From 53a9efb068522a92ad89d487e8aa30389e700ee9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 10 Dec 2025 14:27:12 +0100 Subject: [PATCH 19/33] Update parser error message and tests results. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- libsolidity/parsing/Parser.cpp | 2 +- .../standard_outputs_on_parsing_error/output.json | 4 ++-- .../syntaxTests/freeFunctions/free_constructor.sol | 2 +- test/libsolidity/syntaxTests/freeFunctions/free_fallback.sol | 2 +- test/libsolidity/syntaxTests/freeFunctions/free_receive.sol | 2 +- test/libsolidity/syntaxTests/parsing/unexpected.sol | 2 +- .../layout_specified_by_function_empty_call_options.sol | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index ddffdb600229..77b70267397c 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -170,7 +170,7 @@ ASTPointer Parser::parse(CharStream& _charStream) expectToken(Token::Semicolon); } else - fatalParserError(7858_error, "Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition."); + fatalParserError(7858_error, "Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition."); } } solAssert(m_recursionDepth == 0, ""); diff --git a/test/cmdlineTests/standard_outputs_on_parsing_error/output.json b/test/cmdlineTests/standard_outputs_on_parsing_error/output.json index 6730d772ee02..39610363ee58 100644 --- a/test/cmdlineTests/standard_outputs_on_parsing_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_parsing_error/output.json @@ -3,14 +3,14 @@ { "component": "general", "errorCode": "7858", - "formattedMessage": "ParserError: Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition. + "formattedMessage": "ParserError: Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition. --> C:5:14: | 5 | contract C {}} | ^ ", - "message": "Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition.", + "message": "Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.", "severity": "error", "sourceLocation": { "end": 121, diff --git a/test/libsolidity/syntaxTests/freeFunctions/free_constructor.sol b/test/libsolidity/syntaxTests/freeFunctions/free_constructor.sol index 7878983571ed..5e263606d660 100644 --- a/test/libsolidity/syntaxTests/freeFunctions/free_constructor.sol +++ b/test/libsolidity/syntaxTests/freeFunctions/free_constructor.sol @@ -1,3 +1,3 @@ constructor() {} // ---- -// ParserError 7858: (0-11): Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition. +// ParserError 7858: (0-11): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition. diff --git a/test/libsolidity/syntaxTests/freeFunctions/free_fallback.sol b/test/libsolidity/syntaxTests/freeFunctions/free_fallback.sol index 897ed5964752..cec4c7de07a0 100644 --- a/test/libsolidity/syntaxTests/freeFunctions/free_fallback.sol +++ b/test/libsolidity/syntaxTests/freeFunctions/free_fallback.sol @@ -1,3 +1,3 @@ fallback(){} // ---- -// ParserError 7858: (0-8): Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition. +// ParserError 7858: (0-8): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition. diff --git a/test/libsolidity/syntaxTests/freeFunctions/free_receive.sol b/test/libsolidity/syntaxTests/freeFunctions/free_receive.sol index 83dfee446347..ad021b221482 100644 --- a/test/libsolidity/syntaxTests/freeFunctions/free_receive.sol +++ b/test/libsolidity/syntaxTests/freeFunctions/free_receive.sol @@ -1,3 +1,3 @@ receive() {} // ---- -// ParserError 7858: (0-7): Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition. +// ParserError 7858: (0-7): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition. diff --git a/test/libsolidity/syntaxTests/parsing/unexpected.sol b/test/libsolidity/syntaxTests/parsing/unexpected.sol index c6fae414c387..9dd495c8b529 100644 --- a/test/libsolidity/syntaxTests/parsing/unexpected.sol +++ b/test/libsolidity/syntaxTests/parsing/unexpected.sol @@ -1,3 +1,3 @@ unexpected // ---- -// ParserError 7858: (0-10): Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition. +// ParserError 7858: (0-10): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol index e0b1f4e5cb61..79bcb8878624 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol @@ -3,4 +3,4 @@ contract A { } contract C is A layout at this.f{}() {} // ---- -// ParserError 7858: (98-99): Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition. +// ParserError 7858: (98-99): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition. From dad604cbdfc79f8f70b6c8433082b4b66fe76cec Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 10 Dec 2025 14:37:19 +0100 Subject: [PATCH 20/33] Update changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 42d679caa3df..7ed3d7ef64d9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: Bugfixes: +* Codegen: Fix internal compiler error when emitting events via module member access. * TypeChecker: Fix error and event selectors not being considered compile-time constant. From 2d6ecc5f501f49b6537a6756e12e5a60e9e46cd7 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:49:09 -0300 Subject: [PATCH 21/33] legacy: Fix handling of storage array boundaries (deletion, cleanup, and copy) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Kirchner Co-authored-by: clonker <1685266+clonker@users.noreply.github.com> Co-authored-by: Kamil Śliwak --- libsolidity/codegen/ArrayUtils.cpp | 469 ++++------------------------- libsolidity/codegen/ArrayUtils.h | 10 +- 2 files changed, 68 insertions(+), 411 deletions(-) diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index 455cfe0842ed..841161fa91b6 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -46,256 +46,65 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons // this copies source to target and also clears target if it was larger // need to leave "target_ref target_byte_off" on the stack at the end - // stack layout: [source_ref] [source length] target_ref (top) + // stack layout: source_ref [source length] target_ref (top) solAssert(_targetType.location() == DataLocation::Storage, ""); - Type const* targetBaseType = _targetType.baseType(); - Type const* sourceBaseType = _sourceType.baseType(); - // TODO unroll loop for small sizes - bool sourceIsStorage = _sourceType.location() == DataLocation::Storage; bool fromCalldata = _sourceType.location() == DataLocation::CallData; - bool directCopy = sourceIsStorage && sourceBaseType->isValueType() && *sourceBaseType == *targetBaseType; - bool haveByteOffsetSource = !directCopy && sourceIsStorage && sourceBaseType->storageBytes() <= 16; - bool haveByteOffsetTarget = !directCopy && targetBaseType->storageBytes() <= 16; - unsigned byteOffsetSize = (haveByteOffsetSource ? 1u : 0u) + (haveByteOffsetTarget ? 1u : 0u); + bool haveSourceLengthOnStack = fromCalldata && _sourceType.isDynamicallySized(); - // stack: source_ref [source_length] target_ref - // store target_ref for (unsigned i = _sourceType.sizeOnStack(); i > 0; --i) m_context << swapInstruction(i); // stack: target_ref source_ref [source_length] - if (_targetType.isByteArrayOrString()) + if (_sourceType.baseType()->category() == Type::Category::Array) { - // stack: target_ref source_ref [source_length] - if (fromCalldata && _sourceType.isDynamicallySized()) - { - // stack: target_ref source_ref source_length - m_context << Instruction::SWAP1; - // stack: target_ref source_length source_ref - m_context << Instruction::DUP3; - // stack: target_ref source_length source_ref target_ref - m_context.callYulFunction( - m_context.utilFunctions().copyByteArrayToStorageFunction(_sourceType, _targetType), - 3, - 0 - ); - } - else - { - // stack: target_ref source_ref - m_context << Instruction::DUP2; - // stack: target_ref source_ref target_ref - m_context.callYulFunction( - m_context.utilFunctions().copyByteArrayToStorageFunction(_sourceType, _targetType), - 2, - 0 - ); - } - // stack: target_ref - return; + // TODO: This limitation can now be removed since we use Yul utility functions that handle nested arrays correctly. + // The old inline assembly implementation couldn't handle nested calldata dynamic arrays, but the Yul functions + // support them through recursive calls. We keep this check temporarily for backward compatibility. + auto const& sourceBaseArrayType = dynamic_cast(*_sourceType.baseType()); + solUnimplementedAssert( + !fromCalldata || + !_sourceType.isDynamicallyEncoded() || + !sourceBaseArrayType.isDynamicallySized(), + "Copying nested calldata dynamic arrays to storage is not implemented in the old code generator." + ); } - - // retrieve source length - if (_sourceType.location() != DataLocation::CallData || !_sourceType.isDynamicallySized()) - retrieveLength(_sourceType); // otherwise, length is already there - if (_sourceType.location() == DataLocation::Memory && _sourceType.isDynamicallySized()) + else { - // increment source pointer to point to data - m_context << Instruction::SWAP1 << u256(0x20); - m_context << Instruction::ADD << Instruction::SWAP1; + // TODO: This limitation can now be removed since we use Yul utility functions that handle non-value types correctly. + // The old inline assembly implementation couldn't handle copying arrays of non-value types from memory or calldata to storage, + // but the Yul functions support them. We keep this check temporarily for backward compatibility. + bool fromMemoryOrCalldata = _sourceType.location() == DataLocation::Memory || _sourceType.location() == DataLocation::CallData; + solUnimplementedAssert( + _sourceType.baseType()->isValueType() || !fromMemoryOrCalldata, + "Copying of type " + _sourceType.toString(false) + " to storage is not supported in legacy (only supported by the IR pipeline). " + + "Hint: try compiling with `--via-ir` (CLI) or the equivalent `viaIR: true` (Standard JSON)." + ); } - // stack: target_ref source_ref source_length - Type const* targetType = &_targetType; - Type const* sourceType = &_sourceType; - m_context.callLowLevelFunction( - "$copyArrayToStorage_" + sourceType->identifier() + "_to_" + targetType->identifier(), - 3, - 1, - [=](CompilerContext& _context) - { - ArrayUtils utils(_context); - ArrayType const& _sourceType = dynamic_cast(*sourceType); - ArrayType const& _targetType = dynamic_cast(*targetType); - // stack: target_ref source_ref source_length - _context << Instruction::DUP3; - // stack: target_ref source_ref source_length target_ref - utils.retrieveLength(_targetType); - // stack: target_ref source_ref source_length target_ref target_length - if (_targetType.isDynamicallySized()) - { - // store new target length - solAssert(!_targetType.isByteArrayOrString()); - _context << Instruction::DUP3 << Instruction::DUP3 << Instruction::SSTORE; - } - if (sourceBaseType->category() == Type::Category::Mapping) - { - solAssert(targetBaseType->category() == Type::Category::Mapping, ""); - solAssert(_sourceType.location() == DataLocation::Storage, ""); - // nothing to copy - _context - << Instruction::POP << Instruction::POP - << Instruction::POP << Instruction::POP; - return; - } - // stack: target_ref source_ref source_length target_ref target_length - // compute hashes (data positions) - _context << Instruction::SWAP1; - if (_targetType.isDynamicallySized()) - CompilerUtils(_context).computeHashStatic(); - // stack: target_ref source_ref source_length target_length target_data_pos - _context << Instruction::SWAP1; - utils.convertLengthToSize(_targetType); - _context << Instruction::DUP2 << Instruction::ADD; - // stack: target_ref source_ref source_length target_data_pos target_data_end - _context << Instruction::SWAP3; - // stack: target_ref target_data_end source_length target_data_pos source_ref - - evmasm::AssemblyItem copyLoopEndWithoutByteOffset = _context.newTag(); - solAssert(!_targetType.isByteArrayOrString()); - // skip copying if source length is zero - _context << Instruction::DUP3 << Instruction::ISZERO; - _context.appendConditionalJumpTo(copyLoopEndWithoutByteOffset); - - if (_sourceType.location() == DataLocation::Storage && _sourceType.isDynamicallySized()) - CompilerUtils(_context).computeHashStatic(); - // stack: target_ref target_data_end source_length target_data_pos source_data_pos - _context << Instruction::SWAP2; - utils.convertLengthToSize(_sourceType); - _context << Instruction::DUP3 << Instruction::ADD; - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end - if (haveByteOffsetTarget) - _context << u256(0); - if (haveByteOffsetSource) - _context << u256(0); - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] - evmasm::AssemblyItem copyLoopStart = _context.newTag(); - _context << copyLoopStart; - // check for loop condition - _context - << dupInstruction(3 + byteOffsetSize) << dupInstruction(2 + byteOffsetSize) - << Instruction::GT << Instruction::ISZERO; - evmasm::AssemblyItem copyLoopEnd = _context.appendConditionalJump(); - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] - // copy - if (sourceBaseType->category() == Type::Category::Array) - { - solAssert(byteOffsetSize == 0, "Byte offset for array as base type."); - auto const& sourceBaseArrayType = dynamic_cast(*sourceBaseType); - - solUnimplementedAssert( - _sourceType.location() != DataLocation::CallData || - !_sourceType.isDynamicallyEncoded() || - !sourceBaseArrayType.isDynamicallySized(), - "Copying nested calldata dynamic arrays to storage is not implemented in the old code generator." - ); - _context << Instruction::DUP3; - if (sourceBaseArrayType.location() == DataLocation::Memory) - _context << Instruction::MLOAD; - _context << Instruction::DUP3; - utils.copyArrayToStorage(dynamic_cast(*targetBaseType), sourceBaseArrayType); - _context << Instruction::POP; - } - else if (directCopy) - { - solAssert(byteOffsetSize == 0, "Byte offset for direct copy."); - _context - << Instruction::DUP3 << Instruction::SLOAD - << Instruction::DUP3 << Instruction::SSTORE; - } - else - { - // Note that we have to copy each element on its own in case conversion is involved. - // We might copy too much if there is padding at the last element, but this way end - // checking is easier. - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] - _context << dupInstruction(3 + byteOffsetSize); - if (_sourceType.location() == DataLocation::Storage) - { - if (haveByteOffsetSource) - _context << Instruction::DUP2; - else - _context << u256(0); - StorageItem(_context, *sourceBaseType).retrieveValue(SourceLocation(), true); - } - else if (sourceBaseType->isValueType()) - CompilerUtils(_context).loadFromMemoryDynamic(*sourceBaseType, fromCalldata, true, false); - else - solUnimplemented("Copying of type " + _sourceType.toString(false) + " to storage is not supported in legacy (only supported by the IR pipeline). Hint: try compiling with `--via-ir` (CLI) or the equivalent `viaIR: true` (Standard JSON)"); - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] ... - assertThrow( - 2 + byteOffsetSize + sourceBaseType->sizeOnStack() <= 16, - StackTooDeepError, - util::stackTooDeepString - ); - // fetch target storage reference - _context << dupInstruction(2 + byteOffsetSize + sourceBaseType->sizeOnStack()); - if (haveByteOffsetTarget) - _context << dupInstruction(1 + byteOffsetSize + sourceBaseType->sizeOnStack()); - else - _context << u256(0); - StorageItem(_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true); - } - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] - // increment source - if (haveByteOffsetSource) - utils.incrementByteOffset(sourceBaseType->storageBytes(), 1, haveByteOffsetTarget ? 5 : 4); - else - { - _context << swapInstruction(2 + byteOffsetSize); - if (sourceIsStorage) - _context << sourceBaseType->storageSize(); - else if (_sourceType.location() == DataLocation::Memory) - _context << sourceBaseType->memoryHeadSize(); - else - _context << sourceBaseType->calldataHeadSize(); - _context - << Instruction::ADD - << swapInstruction(2 + byteOffsetSize); - } - // increment target - if (haveByteOffsetTarget) - utils.incrementByteOffset(targetBaseType->storageBytes(), byteOffsetSize, byteOffsetSize + 2); - else - _context - << swapInstruction(1 + byteOffsetSize) - << targetBaseType->storageSize() - << Instruction::ADD - << swapInstruction(1 + byteOffsetSize); - _context.appendJumpTo(copyLoopStart); - _context << copyLoopEnd; - if (haveByteOffsetTarget) - { - // clear elements that might be left over in the current slot in target - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end target_byte_offset [source_byte_offset] - _context << dupInstruction(byteOffsetSize) << Instruction::ISZERO; - evmasm::AssemblyItem copyCleanupLoopEnd = _context.appendConditionalJump(); - _context << dupInstruction(2 + byteOffsetSize) << dupInstruction(1 + byteOffsetSize); - StorageItem(_context, *targetBaseType).setToZero(SourceLocation(), true); - utils.incrementByteOffset(targetBaseType->storageBytes(), byteOffsetSize, byteOffsetSize + 2); - _context.appendJumpTo(copyLoopEnd); - - _context << copyCleanupLoopEnd; - _context << Instruction::POP; // might pop the source, but then target is popped next - } - if (haveByteOffsetSource) - _context << Instruction::POP; - _context << copyLoopEndWithoutByteOffset; + if (haveSourceLengthOnStack) + { + // stack: target_ref source_ref source_length + m_context << Instruction::SWAP1; + // stack: target_ref source_length source_ref + m_context << Instruction::DUP3; + // stack: target_ref source_length source_ref target_ref + } + else + { + // stack: target_ref source_ref + m_context << Instruction::DUP2; + // stack: target_ref source_ref target_ref + } - // zero-out leftovers in target - // stack: target_ref target_data_end source_data_pos target_data_pos_updated source_data_end - _context << Instruction::POP << Instruction::SWAP1 << Instruction::POP; - // stack: target_ref target_data_end target_data_pos_updated - if (targetBaseType->storageBytes() < 32) - utils.clearStorageLoop(TypeProvider::uint256()); - else - utils.clearStorageLoop(targetBaseType); - _context << Instruction::POP; - } + m_context.callYulFunction( + m_context.utilFunctions().copyArrayToStorageFunction(_sourceType, _targetType), + haveSourceLengthOnStack ? 3 : 2, + 0 ); + // stack: target_ref } void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWordBoundaries) const @@ -586,9 +395,9 @@ void ArrayUtils::clearArray(ArrayType const& _typeIn) const } else { - _context << Instruction::DUP1 << _type.length(); + _context << _type.length(); ArrayUtils(_context).convertLengthToSize(_type); - _context << Instruction::ADD << Instruction::SWAP1; + // stack: storage_ref slot_count if (_type.baseType()->storageBytes() < 32) ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256()); else @@ -623,13 +432,12 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const } // stack: ref old_length convertLengthToSize(_type); - // compute data positions + // stack: ref slot_count m_context << Instruction::SWAP1; CompilerUtils(m_context).computeHashStatic(); - // stack: len data_pos - m_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD - << Instruction::SWAP1; - // stack: data_pos_end data_pos + // stack: slot_count data_pos + m_context << Instruction::SWAP1; + // stack: data_pos slot_count if (_type.storageStride() < 32) clearStorageLoop(TypeProvider::uint256()); else @@ -639,156 +447,6 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const m_context << Instruction::POP; } -void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const -{ - Type const* type = &_typeIn; - m_context.callLowLevelFunction( - "$resizeDynamicArray_" + _typeIn.identifier(), - 2, - 0, - [type](CompilerContext& _context) - { - ArrayType const& _type = dynamic_cast(*type); - solAssert(_type.location() == DataLocation::Storage, ""); - solAssert(_type.isDynamicallySized(), ""); - if (!_type.isByteArrayOrString() && _type.baseType()->storageBytes() < 32) - solAssert(_type.baseType()->isValueType(), "Invalid storage size for non-value type."); - - unsigned stackHeightStart = _context.stackHeight(); - evmasm::AssemblyItem resizeEnd = _context.newTag(); - - // stack: ref new_length - // fetch old length - ArrayUtils(_context).retrieveLength(_type, 1); - // stack: ref new_length old_length - solAssert(_context.stackHeight() - stackHeightStart == 3 - 2, "2"); - - // Special case for short byte arrays, they are stored together with their length - if (_type.isByteArrayOrString()) - { - evmasm::AssemblyItem regularPath = _context.newTag(); - // We start by a large case-distinction about the old and new length of the byte array. - - _context << Instruction::DUP3 << Instruction::SLOAD; - // stack: ref new_length current_length ref_value - - solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); - _context << Instruction::DUP2 << u256(31) << Instruction::LT; - evmasm::AssemblyItem currentIsLong = _context.appendConditionalJump(); - _context << Instruction::DUP3 << u256(31) << Instruction::LT; - evmasm::AssemblyItem newIsLong = _context.appendConditionalJump(); - - // Here: short -> short - - // Compute 1 << (256 - 8 * new_size) - evmasm::AssemblyItem shortToShort = _context.newTag(); - _context << shortToShort; - _context << Instruction::DUP3 << u256(8) << Instruction::MUL; - _context << u256(0x100) << Instruction::SUB; - _context << u256(2) << Instruction::EXP; - // Divide and multiply by that value, clearing bits. - _context << Instruction::DUP1 << Instruction::SWAP2; - _context << Instruction::DIV << Instruction::MUL; - // Insert 2*length. - _context << Instruction::DUP3 << Instruction::DUP1 << Instruction::ADD; - _context << Instruction::OR; - // Store. - _context << Instruction::DUP4 << Instruction::SSTORE; - solAssert(_context.stackHeight() - stackHeightStart == 3 - 2, "3"); - _context.appendJumpTo(resizeEnd); - - _context.adjustStackOffset(1); // we have to do that because of the jumps - // Here: short -> long - - _context << newIsLong; - // stack: ref new_length current_length ref_value - solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); - // Zero out lower-order byte. - _context << u256(0xff) << Instruction::NOT << Instruction::AND; - // Store at data location. - _context << Instruction::DUP4; - CompilerUtils(_context).computeHashStatic(); - _context << Instruction::SSTORE; - // stack: ref new_length current_length - // Store new length: Compute 2*length + 1 and store it. - _context << Instruction::DUP2 << Instruction::DUP1 << Instruction::ADD; - _context << u256(1) << Instruction::ADD; - // stack: ref new_length current_length 2*new_length+1 - _context << Instruction::DUP4 << Instruction::SSTORE; - solAssert(_context.stackHeight() - stackHeightStart == 3 - 2, "3"); - _context.appendJumpTo(resizeEnd); - - _context.adjustStackOffset(1); // we have to do that because of the jumps - - _context << currentIsLong; - _context << Instruction::DUP3 << u256(31) << Instruction::LT; - _context.appendConditionalJumpTo(regularPath); - - // Here: long -> short - // Read the first word of the data and store it on the stack. Clear the data location and - // then jump to the short -> short case. - - // stack: ref new_length current_length ref_value - solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); - _context << Instruction::POP << Instruction::DUP3; - CompilerUtils(_context).computeHashStatic(); - _context << Instruction::DUP1 << Instruction::SLOAD << Instruction::SWAP1; - // stack: ref new_length current_length first_word data_location - _context << Instruction::DUP3; - ArrayUtils(_context).convertLengthToSize(_type); - _context << Instruction::DUP2 << Instruction::ADD << Instruction::SWAP1; - // stack: ref new_length current_length first_word data_location_end data_location - ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256()); - _context << Instruction::POP; - // stack: ref new_length current_length first_word - solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); - _context.appendJumpTo(shortToShort); - - _context << regularPath; - // stack: ref new_length current_length ref_value - _context << Instruction::POP; - } - - // Change of length for a regular array (i.e. length at location, data at KECCAK256(location)). - // stack: ref new_length old_length - // store new length - _context << Instruction::DUP2; - if (_type.isByteArrayOrString()) - // For a "long" byte array, store length as 2*length+1 - _context << Instruction::DUP1 << Instruction::ADD << u256(1) << Instruction::ADD; - _context << Instruction::DUP4 << Instruction::SSTORE; - // skip if size is not reduced - _context << Instruction::DUP2 << Instruction::DUP2 - << Instruction::GT << Instruction::ISZERO; - _context.appendConditionalJumpTo(resizeEnd); - - // size reduced, clear the end of the array - // stack: ref new_length old_length - ArrayUtils(_context).convertLengthToSize(_type); - _context << Instruction::DUP2; - ArrayUtils(_context).convertLengthToSize(_type); - // stack: ref new_length old_size new_size - // compute data positions - _context << Instruction::DUP4; - CompilerUtils(_context).computeHashStatic(); - // stack: ref new_length old_size new_size data_pos - _context << Instruction::SWAP2 << Instruction::DUP3 << Instruction::ADD; - // stack: ref new_length data_pos new_size delete_end - _context << Instruction::SWAP2 << Instruction::ADD; - // stack: ref new_length delete_end delete_start - if (_type.storageStride() < 32) - ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256()); - else - ArrayUtils(_context).clearStorageLoop(_type.baseType()); - - _context << resizeEnd; - // cleanup - _context << Instruction::POP << Instruction::POP << Instruction::POP; - solAssert(_context.stackHeight() == stackHeightStart - 2, ""); - } - ); -} - void ArrayUtils::incrementDynamicArraySize(ArrayType const& _type) const { solAssert(_type.location() == DataLocation::Storage, ""); @@ -936,29 +594,32 @@ void ArrayUtils::clearStorageLoop(Type const* _type) const _context << Instruction::POP; return; } - // stack: end_pos pos - + // stack: start_pos slot_count + // Initialize loop counter i = 0 + _context << u256(0); + // stack: start_pos slot_count i evmasm::AssemblyItem loopStart = _context.appendJumpToNew(); _context << loopStart; - // check for loop condition - _context << - Instruction::DUP1 << - Instruction::DUP3 << - Instruction::GT << - Instruction::ISZERO; + // check for loop condition: !(slot_count > i) = (i >= slot_count) + _context << Instruction::DUP1 << Instruction::DUP3 << Instruction::GT << Instruction::ISZERO; evmasm::AssemblyItem zeroLoopEnd = _context.newTag(); _context.appendConditionalJumpTo(zeroLoopEnd); - // delete + // stack: start_pos slot_count i + // compute storage position: start_pos + i + _context << Instruction::DUP3 << Instruction::DUP2 << Instruction::ADD; + // stack: start_pos slot_count i (start_pos+i) + // delete storage slot _context << u256(0); - StorageItem(_context, *_type).setToZero(SourceLocation(), false); - _context << Instruction::POP; - // increment + StorageItem(_context, *_type).setToZero(SourceLocation(), /* _removeReference = */ true); + // stack: start_pos slot_count i + // increment counter: i += storageSize _context << _type->storageSize() << Instruction::ADD; _context.appendJumpTo(loopStart); // cleanup _context << zeroLoopEnd; - _context << Instruction::POP; - + // stack: start_pos slot_count i + _context << Instruction::POP << Instruction::POP; + // stack: start_pos solAssert(_context.stackHeight() == stackHeightStart - 1, ""); } ); diff --git a/libsolidity/codegen/ArrayUtils.h b/libsolidity/codegen/ArrayUtils.h index 326084cb63a8..a62df8a7b2ab 100644 --- a/libsolidity/codegen/ArrayUtils.h +++ b/libsolidity/codegen/ArrayUtils.h @@ -61,10 +61,6 @@ class ArrayUtils /// Stack pre: reference (excludes byte offset) /// Stack post: void clearDynamicArray(ArrayType const& _type) const; - /// Changes the size of a dynamic array and clears the tail if it is shortened. - /// Stack pre: reference (excludes byte offset) new_length - /// Stack post: - void resizeDynamicArray(ArrayType const& _type) const; /// Increments the size of a dynamic array by one. /// Does not touch the new data element. In case of a byte array, this might move the /// data. @@ -76,9 +72,9 @@ class ArrayUtils /// Stack pre: reference /// Stack post: void popStorageArrayElement(ArrayType const& _type) const; - /// Appends a loop that clears a sequence of storage slots of the given type (excluding end). - /// Stack pre: end_ref start_ref - /// Stack post: end_ref + /// Appends a loop that clears a sequence of storage slots of the given type. + /// Stack pre: start_ref slot_count + /// Stack post: start_ref void clearStorageLoop(Type const* _type) const; /// Converts length to size (number of storage slots or calldata/memory bytes). /// if @a _pad then add padding to multiples of 32 bytes for calldata/memory. From eb4149477d6663fc61b59eacf5b4df4125a6c710 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:49:14 -0300 Subject: [PATCH 22/33] via-ir: Fix handling of storage array boundaries (deletion and cleanup) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Kirchner Co-authored-by: Kamil Śliwak --- libsolidity/codegen/YulUtilFunctions.cpp | 43 +++++++++++++++--------- libsolidity/codegen/YulUtilFunctions.h | 11 +++--- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index ffeaa790e1e8..4c0a7026928a 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -1419,14 +1419,13 @@ std::string YulUtilFunctions::cleanUpStorageArrayEndFunction(ArrayType const& _t let newSlotCount := (startIndex) let arrayDataStart := (array) let deleteStart := add(arrayDataStart, newSlotCount) - let deleteEnd := add(arrayDataStart, oldSlotCount) // if we are dealing with packed array and offset is greater than zero // we have to partially clear last slot that is still used, so decreasing start by one let offset := mul(mod(startIndex, ), ) if gt(offset, 0) { (sub(deleteStart, 1), offset) } - (deleteStart, deleteEnd) + (deleteStart, sub(oldSlotCount, newSlotCount)) } )") ("convertToSize", arrayConvertLengthToSize(_type)) @@ -1474,11 +1473,17 @@ std::string YulUtilFunctions::cleanUpDynamicByteArrayEndSlotsFunction(ArrayType _args = {"array", "len", "startIndex"}; return Whiskers(R"( if gt(len, 31) { - let dataArea := (array) - let deleteStart := add(dataArea, (startIndex)) - // If we are clearing array to be short byte array, we want to clear only data starting from array data area. - if lt(startIndex, 32) { deleteStart := dataArea } - (deleteStart, add(dataArea, (len))) + if gt(len, startIndex) { + let dataArea := (array) + let oldSlotCount := (len) + let newSlotCount := (startIndex) + // If we are clearing array to be short byte array, we want to clear only data starting from array data area. + if lt(startIndex, 32) { + newSlotCount := 0 + } + let deleteStart := add(dataArea, newSlotCount) + (deleteStart, sub(oldSlotCount, newSlotCount)) + } } )") ("dataLocation", arrayDataAreaFunction(_type)) @@ -1496,14 +1501,21 @@ std::string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _ty function (array, data, oldLen, newLen) { switch lt(newLen, 32) case 0 { + // NOTE: This branch (newLen >= 32) is currently unreachable from Solidity code. + // All delete operations use newLen=0, and assignment uses copyByteArrayToStorageFunction. + // However, we maintain correct logic here for future-proofing and consistency. + let newSlots := (newLen) + let oldSlots := (oldLen) let arrayDataStart := (array) - let deleteStart := add(arrayDataStart, (newLen)) + let deleteStart := add(arrayDataStart, newSlots) // we have to partially clear last slot that is still used let offset := and(newLen, 0x1f) if offset { (sub(deleteStart, 1), offset) } - (deleteStart, add(arrayDataStart, (oldLen))) + if gt(oldSlots, newSlots) { + (deleteStart, sub(oldSlots, newSlots)) + } sstore(array, or(mul(2, newLen), 1)) } @@ -1511,8 +1523,9 @@ std::string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _ty switch gt(oldLen, 31) case 1 { let arrayDataStart := (array) - // clear whole old array, as we are transforming to short bytes array - (add(arrayDataStart, 1), add(arrayDataStart, (oldLen))) + // Clear whole old array, as we are transforming to short bytes array. + // () will clear the first slot after copying its content. + (add(arrayDataStart, 1), sub((oldLen), 1)) (array, newLen) } default { @@ -1826,10 +1839,10 @@ std::string YulUtilFunctions::clearStorageRangeFunction(Type const& _type) return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( - function (start, end) { - for {} lt(start, end) { start := add(start, ) } + function (startSlot, slotCount) { + for { let i := 0 } lt(i, slotCount) { i := add(i, ) } { - (start, 0) + (add(startSlot, i), 0) } } )") @@ -1861,7 +1874,7 @@ std::string YulUtilFunctions::clearStorageArrayFunction(ArrayType const& _type) (slot, 0) - (slot, add(slot, ())) + (slot, ()) } )") diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index c28ba855c816..f4172017b44e 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -266,8 +266,11 @@ class YulUtilFunctions std::string storageArrayPushZeroFunction(ArrayType const& _type); /// @returns the name of a function that will clear the storage area given - /// by the start and end (exclusive) parameters (slots). - /// signature: (start, end) + /// by the start position and number of slots to clear. The start position is in terms of storage slots and we + /// assume that the beginning of the clear range starts at the beginning of the start slot. + /// `slot_count` is assumed to be a multiple of `_type.storageSize()`. The function clears storage in increments + /// of `_type.storageSize()` and does not perform any runtime checks. + /// signature: (start_slot, slot_count) std::string clearStorageRangeFunction(Type const& _type); /// @returns the name of a function that will clear the given storage array @@ -297,7 +300,7 @@ class YulUtilFunctions /// The function reverts for too large lengths. std::string arrayAllocationSizeFunction(ArrayType const& _type); - /// @returns the name of a function that converts a storage slot number + /// @returns the name of a function that converts a storage slot number, /// a memory pointer or a calldata pointer to the slot number / memory pointer / calldata pointer /// for the data position of an array which is stored in that slot / memory area / calldata area. std::string arrayDataAreaFunction(ArrayType const& _type); @@ -618,7 +621,7 @@ class YulUtilFunctions std::string cleanUpDynamicByteArrayEndSlotsFunction(ArrayType const& _type); /// @returns the name of a function that increases size of byte array - /// when we resize byte array frextractUsedSetLenom < 32 elements to >= 32 elements or we push to byte array of size 31 copying of data will occur + /// when we resize byte array from < 32 elements to >= 32 elements or we push to byte array of size 31 copying of data will occur /// signature: (array, data, oldLen, newLen) std::string increaseByteArraySizeFunction(ArrayType const& _type); From 4f0e20cf36e1107141f5b9aef13adddb1e05c03d Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:48:21 -0300 Subject: [PATCH 23/33] Add test for arrays at storage boundaries and extend coverage of legacy and via-ir on deletion, partial assigments and copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Kirchner Co-authored-by: Kamil Śliwak --- test/libsolidity/SolidityOptimizer.cpp | 4 +- .../abi_decode_simple_storage.sol | 4 +- .../abiEncoderV1/abi_decode_v2_storage.sol | 4 +- .../struct/struct_storage_ptr.sol | 6 +- .../calldata_overlapped_dynamic_arrays.sol | 6 +- .../abiEncoderV2/storage_array_encoding.sol | 10 +- .../arrays_complex_from_and_to_storage.sol | 6 +- .../array/bytes_length_member.sol | 4 +- .../array/constant_var_as_array_length.sol | 4 +- .../copying/array_copy_calldata_storage.sol | 6 +- .../copying/array_copy_cleanup_uint128.sol | 6 +- .../copying/array_copy_cleanup_uint40.sol | 6 +- .../copying/array_copy_clear_storage.sol | 6 +- .../array_copy_clear_storage_packed.sol | 12 +- .../copying/array_copy_different_packing.sol | 4 +- .../copying/array_copy_including_array.sol | 12 +- .../array/copying/array_copy_nested_array.sol | 6 +- ...ay_copy_storage_storage_different_base.sol | 4 +- ..._storage_storage_different_base_nested.sol | 6 +- .../array_copy_storage_storage_dyn_dyn.sol | 6 +- ...y_copy_storage_storage_dynamic_dynamic.sol | 4 +- ...ay_copy_storage_storage_static_dynamic.sol | 4 +- ...ray_copy_storage_storage_static_simple.sol | 4 +- ...ray_copy_storage_storage_static_static.sol | 6 +- .../array_copy_storage_storage_struct.sol | 6 +- .../copying/array_copy_target_leftover.sol | 6 +- .../copying/array_copy_target_leftover2.sol | 6 +- .../copying/array_copy_target_simple.sol | 6 +- .../copying/array_copy_target_simple_2.sol | 6 +- .../copying/array_elements_to_mapping.sol | 6 +- .../array_nested_calldata_to_storage.sol | 4 +- .../array_nested_memory_to_storage.sol | 14 +- ...on_external_storage_to_storage_dynamic.sol | 6 +- ...o_storage_dynamic_different_mutability.sol | 6 +- .../array_of_struct_calldata_to_storage.sol | 2 +- ..._containing_arrays_calldata_to_storage.sol | 2 +- .../array/copying/array_to_mapping.sol | 6 +- .../copying/arrays_from_and_to_storage.sol | 4 +- .../array/copying/bytes_inside_mappings.sol | 7 +- .../copying/bytes_storage_to_storage.sol | 23 +-- .../calldata_array_dynamic_to_storage.sol | 6 +- ...nup_during_multi_element_per_slot_copy.sol | 12 +- .../copy_byte_array_in_struct_to_storage.sol | 9 +- .../copying/copy_byte_array_to_storage.sol | 6 +- .../copy_function_internal_storage_array.sol | 6 +- ...opy_internal_function_array_to_storage.sol | 4 +- .../array/copying/copy_removes_bytes_data.sol | 3 +- .../copying/copying_bytes_multiassign.sol | 6 +- ...d_array_of_structs_calldata_to_storage.sol | 6 +- ...ted_array_of_structs_memory_to_storage.sol | 6 +- .../function_type_array_to_storage.sol | 12 +- .../memory_dyn_2d_bytes_to_storage.sol | 6 +- ...sted_array_element_calldata_to_storage.sol | 2 +- ...nested_array_element_memory_to_storage.sol | 2 +- ...ested_array_element_storage_to_storage.sol | 12 +- ...d_array_of_structs_calldata_to_storage.sol | 6 +- ...ted_array_of_structs_memory_to_storage.sol | 6 +- ...amic_array_element_calldata_to_storage.sol | 4 +- .../copying/storage_memory_nested_bytes.sol | 2 +- .../array/delete/bytes_delete_element.sol | 4 +- .../array/delete/delete_bytes_array.sol | 1 + .../delete/delete_storage_array_packed.sol | 6 +- .../array/fixed_array_cleanup.sol | 6 +- ...nvalid_encoding_for_storage_byte_array.sol | 6 +- .../long_byte_array_cleanup_after_delete.sol | 77 ++++++++ ...rray_cleanup_after_overwrite_with_long.sol | 105 +++++++++++ .../array/nested_calldata_storage2.sol | 2 +- .../array/pop/array_pop_array_transition.sol | 6 +- .../push/array_push_nested_from_calldata.sol | 4 +- .../array/push/array_push_struct.sol | 4 +- .../array/push/nested_bytes_push.sol | 2 +- .../copy_from_calldata_removes_bytes_data.sol | 3 +- .../cleanup/byte_array_to_storage_cleanup.sol | 13 +- .../constructor/arrays_in_constructors.sol | 4 +- .../bytes_in_constructors_packer.sol | 6 +- .../bytes_in_constructors_unpacker.sol | 6 +- .../constructor_static_array_argument.sol | 4 +- .../event_dynamic_nested_array_storage_v2.sol | 2 +- .../fallback/call_forward_bytes.sol | 1 + .../storage/empty_nonempty_empty.sol | 5 +- .../storage/static_array_copy_cleanup.sol | 94 ++++++++++ ...ray_and_partial_assignment_with_layout.sol | 54 ++++++ .../storage_boundary_array_assignment.sol | 28 +++ .../storage/storage_boundary_array_copy.sol | 61 +++++++ .../storage/storage_boundary_array_delete.sol | 34 ++++ ...dary_array_delete_overlapping_variable.sol | 40 ++++ ...array_packing_not_overlapping_variable.sol | 63 +++++++ ...rage_boundary_array_partial_assignment.sol | 41 +++++ .../storage_boundary_delete_overflow_bug.sol | 80 ++++++++ .../storage/storage_boundary_packed_array.sol | 35 ++++ ...rage_boundary_struct_array_mixed_types.sol | 172 ++++++++++++++++++ ...torage_boundary_struct_array_multislot.sol | 128 +++++++++++++ .../storage_boundary_struct_array_packed.sol | 128 +++++++++++++ .../storage/storage_packed_array_copy.sol | 35 ++++ .../state_variable_dynamic_array.sol | 6 +- .../state_variable_mapping.sol | 2 +- .../structs/copy_from_mapping.sol | 4 +- .../copy_struct_array_from_storage.sol | 4 +- .../copy_substructures_from_mapping.sol | 4 +- .../structs/copy_substructures_to_mapping.sol | 12 +- .../semanticTests/structs/copy_to_mapping.sol | 12 +- ...truct_containing_bytes_copy_and_delete.sol | 4 +- .../struct_delete_storage_nested_small.sol | 2 +- .../struct_delete_storage_with_array.sol | 12 +- ...truct_delete_storage_with_arrays_small.sol | 2 +- .../mapping/copy_from_mapping_to_mapping.sol | 4 +- .../userDefinedValueType/calldata.sol | 12 +- .../calldata_to_storage.sol | 10 +- .../memory_to_storage.sol | 8 +- .../semanticTests/various/address_code.sol | 6 +- .../semanticTests/various/create_calldata.sol | 6 +- .../various/destructuring_assignment.sol | 6 +- .../skip_dynamic_types_for_structs.sol | 4 +- ...alldata_struct_array_to_storage_legacy.sol | 16 ++ ..._memory_struct_array_to_storage_legacy.sol | 17 ++ 115 files changed, 1502 insertions(+), 277 deletions(-) create mode 100644 test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_delete.sol create mode 100644 test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_overwrite_with_long.sol create mode 100644 test/libsolidity/semanticTests/storage/static_array_copy_cleanup.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_array_and_partial_assignment_with_layout.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_array_assignment.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_array_copy.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_array_delete.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_array_delete_overlapping_variable.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_array_packing_not_overlapping_variable.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_array_partial_assignment.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_delete_overflow_bug.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_packed_array.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_struct_array_mixed_types.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_struct_array_multislot.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_boundary_struct_array_packed.sol create mode 100644 test/libsolidity/semanticTests/storage/storage_packed_array_copy.sol create mode 100644 test/libsolidity/syntaxTests/array/copy_calldata_struct_array_to_storage_legacy.sol create mode 100644 test/libsolidity/syntaxTests/array/copy_memory_struct_array_to_storage_legacy.sol diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 832299baff92..b3116a37223f 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -634,8 +634,8 @@ BOOST_AUTO_TEST_CASE(optimise_multi_stores) )"; compileBothVersions(sourceCode); compareVersions("f()"); - BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 8); - BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 7); + BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 9); + BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 6); } BOOST_AUTO_TEST_CASE(optimise_constant_to_codecopy) diff --git a/test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple_storage.sol index 54ce693d5ca4..6c4fd52b36ed 100644 --- a/test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple_storage.sol @@ -8,6 +8,6 @@ contract C { } // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" -// gas irOptimized: 135499 +// gas irOptimized: 135441 // gas legacy: 137095 -// gas legacyOptimized: 135823 +// gas legacyOptimized: 135828 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol index 5c3bcba971c2..e5aa910ce1be 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol @@ -21,6 +21,6 @@ contract C { } // ---- // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb -// gas irOptimized: 203167 +// gas irOptimized: 203109 // gas legacy: 206263 -// gas legacyOptimized: 203172 +// gas legacyOptimized: 203177 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index ed983c77b506..ff98c66ca9c6 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -24,6 +24,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 166761 -// gas legacy: 169273 -// gas legacyOptimized: 167243 +// gas irOptimized: 166766 +// gas legacy: 170486 +// gas legacyOptimized: 167252 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol index aa1e494c2133..302aeb5de4d5 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol @@ -33,8 +33,8 @@ contract C { // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2 // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE // f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2 -// gas irOptimized: 111409 -// gas legacy: 112707 -// gas legacyOptimized: 111845 +// gas irOptimized: 111356 +// gas legacy: 113826 +// gas legacyOptimized: 111724 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol index 9599af6c8815..31f759d3bfd4 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol @@ -18,10 +18,10 @@ contract C { // EVMVersion: >homestead // ---- // h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 -// gas irOptimized: 180080 -// gas legacy: 184233 -// gas legacyOptimized: 180856 +// gas irOptimized: 180022 +// gas legacy: 186541 +// gas legacyOptimized: 180429 // i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 // gas irOptimized: 112031 -// gas legacy: 115091 -// gas legacyOptimized: 112657 +// gas legacy: 116683 +// gas legacyOptimized: 112303 diff --git a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol index a9d08ec0c0cb..ac3cd8495f73 100644 --- a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol @@ -12,9 +12,9 @@ contract Test { } // ---- // set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06 -// gas irOptimized: 185216 -// gas legacy: 211054 -// gas legacyOptimized: 206077 +// gas irOptimized: 185221 +// gas legacy: 199970 +// gas legacyOptimized: 186342 // data(uint256,uint256): 0x02, 0x02 -> 0x09 // data(uint256,uint256): 0x05, 0x01 -> 0x11 // data(uint256,uint256): 0x06, 0x00 -> FAILURE diff --git a/test/libsolidity/semanticTests/array/bytes_length_member.sol b/test/libsolidity/semanticTests/array/bytes_length_member.sol index 5159538bc1de..85b9282c6603 100644 --- a/test/libsolidity/semanticTests/array/bytes_length_member.sol +++ b/test/libsolidity/semanticTests/array/bytes_length_member.sol @@ -13,7 +13,7 @@ contract c { // ---- // getLength() -> 0 // set(): 1, 2 -> true -// gas irOptimized: 110422 +// gas irOptimized: 110393 // gas legacy: 110951 -// gas legacyOptimized: 110576 +// gas legacyOptimized: 110577 // getLength() -> 68 diff --git a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol index 342f3218fcb4..833c9dec3e42 100644 --- a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol +++ b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol @@ -10,9 +10,9 @@ contract C { // constructor(): 1, 2, 3 -> // gas irOptimized: 124991 // gas irOptimized code: 14800 -// gas legacy: 134317 +// gas legacy: 142553 // gas legacy code: 46200 -// gas legacyOptimized: 127166 +// gas legacyOptimized: 126306 // gas legacyOptimized code: 23400 // a(uint256): 0 -> 1 // a(uint256): 1 -> 2 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol index ecfe565f12cb..8131e7434d25 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol @@ -20,7 +20,7 @@ contract c { } // ---- // store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32 -// gas irOptimized: 647725 -// gas legacy: 694354 -// gas legacyOptimized: 693849 +// gas irOptimized: 647730 +// gas legacy: 659420 +// gas legacyOptimized: 648899 // retrieve() -> 9, 28, 9, 28, 4, 3, 32 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol index e1cfa7ce7e81..ba05d8fb670d 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol @@ -21,6 +21,6 @@ contract C { } // ---- // f() -> true -// gas irOptimized: 73992 -// gas legacy: 74395 -// gas legacyOptimized: 73794 +// gas irOptimized: 73981 +// gas legacy: 75550 +// gas legacyOptimized: 73812 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol index d65f4f37c104..e4e7bf62f3a0 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol @@ -46,6 +46,6 @@ contract C { } // ---- // f() -> true -// gas irOptimized: 122541 -// gas legacy: 124643 -// gas legacyOptimized: 122801 +// gas irOptimized: 122596 +// gas legacy: 125651 +// gas legacyOptimized: 121668 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol index e9f1448a27b1..f206b432c9a5 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol @@ -13,6 +13,6 @@ contract C { } // ---- // f() -> 0 -// gas irOptimized: 108229 -// gas legacy: 108216 -// gas legacyOptimized: 107625 +// gas irOptimized: 108096 +// gas legacy: 110351 +// gas legacyOptimized: 107708 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol index 43827773c196..12d9bf1fd3c0 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol @@ -40,11 +40,11 @@ contract C { } // ---- // f() -> 0 -// gas irOptimized: 74056 -// gas legacy: 74372 -// gas legacyOptimized: 73796 +// gas irOptimized: 74044 +// gas legacy: 75528 +// gas legacyOptimized: 73861 // g() -> 0 // h() -> 0 -// gas irOptimized: 74126 -// gas legacy: 74398 -// gas legacyOptimized: 73833 +// gas irOptimized: 74114 +// gas legacy: 75553 +// gas legacyOptimized: 73904 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol index ee564d01a2d9..1bbb541911a0 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol @@ -19,5 +19,5 @@ contract c { // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 // gas irOptimized: 208415 -// gas legacy: 220711 -// gas legacyOptimized: 220097 +// gas legacy: 220059 +// gas legacyOptimized: 211458 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol index bb621fcc84b5..ba50c7300f65 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol @@ -35,12 +35,12 @@ contract c { } // ---- // test() -> 0x02000202 -// gas irOptimized: 4549676 -// gas legacy: 4475394 -// gas legacyOptimized: 4447665 +// gas irOptimized: 4560468 +// gas legacy: 4536566 +// gas legacyOptimized: 4456759 // storageEmpty -> 1 // clear() -> 0, 0 -// gas irOptimized: 4478184 -// gas legacy: 4407185 -// gas legacyOptimized: 4381337 +// gas irOptimized: 4488719 +// gas legacy: 4407780 +// gas legacyOptimized: 4385089 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol index 2d325a804bfa..34d6c75ef8a6 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol @@ -12,6 +12,6 @@ contract c { } // ---- // test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 -// gas irOptimized: 689552 -// gas legacy: 686176 -// gas legacyOptimized: 685611 +// gas irOptimized: 689539 +// gas legacy: 713478 +// gas legacyOptimized: 690424 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol index 54639df55d66..af31d4b8e495 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol @@ -18,5 +18,5 @@ contract c { // ---- // test() -> 5, 4 // gas irOptimized: 205667 -// gas legacy: 213863 -// gas legacyOptimized: 212901 +// gas legacy: 207971 +// gas legacyOptimized: 204828 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol index ad745ff4203f..6b1dd7ff02c0 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol @@ -21,6 +21,6 @@ contract c { } // ---- // test() -> 3, 4 -// gas irOptimized: 169669 -// gas legacy: 175415 -// gas legacyOptimized: 172533 +// gas irOptimized: 169553 +// gas legacy: 182361 +// gas legacyOptimized: 169554 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol index a38685404dc7..98e2f5adb45e 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol @@ -15,9 +15,9 @@ contract c { // ---- // setData1(uint256,uint256,uint256): 10, 5, 4 -> // copyStorageStorage() -> -// gas irOptimized: 111350 -// gas legacy: 109272 -// gas legacyOptimized: 109262 +// gas irOptimized: 111321 +// gas legacy: 112434 +// gas legacyOptimized: 111494 // getData2(uint256): 5 -> 10, 4 // setData1(uint256,uint256,uint256): 0, 0, 0 -> // copyStorageStorage() -> diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol index 83df3aef8f43..5a66704b5506 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol @@ -18,5 +18,5 @@ contract c { // ---- // test() -> 5, 4 // gas irOptimized: 253591 -// gas legacy: 250892 -// gas legacyOptimized: 250045 +// gas legacy: 253664 +// gas legacyOptimized: 252200 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol index 94e57c96da7b..29d8bc0ebed7 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol @@ -12,5 +12,5 @@ contract c { // ---- // test() -> 9, 4 // gas irOptimized: 123180 -// gas legacy: 123566 -// gas legacyOptimized: 123202 +// gas legacy: 124642 +// gas legacyOptimized: 123345 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol index 84642c143901..29e62dd3ce8f 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol @@ -11,5 +11,5 @@ contract C { } // ---- // test() -> left(0x01), left(0x02) -// gas legacy: 89698 -// gas legacyOptimized: 88928 +// gas legacy: 69235 +// gas legacyOptimized: 66974 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol index d1f2cbdedcde..65ce656548eb 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol @@ -14,6 +14,6 @@ contract c { } // ---- // test() -> 8, 0 -// gas irOptimized: 196251 -// gas legacy: 194842 -// gas legacyOptimized: 194281 +// gas irOptimized: 196370 +// gas legacy: 210073 +// gas legacyOptimized: 196759 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol index e638f2dad10c..f1cd76a3adc5 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol @@ -17,7 +17,7 @@ contract c { } // ---- // test() -> 4, 5 -// gas irOptimized: 190628 -// gas legacy: 190828 -// gas legacyOptimized: 189657 +// gas irOptimized: 190676 +// gas legacy: 210706 +// gas legacyOptimized: 190472 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol index 22105f6429b9..2deb372fa381 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 100496 -// gas legacy: 158109 -// gas legacyOptimized: 141019 +// gas irOptimized: 100506 +// gas legacy: 146700 +// gas legacyOptimized: 122680 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol index dd49c7a97b6e..706130082fff 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol @@ -19,6 +19,6 @@ contract c { } // ---- // test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0 -// gas irOptimized: 91348 -// gas legacy: 96648 -// gas legacyOptimized: 93841 +// gas irOptimized: 91320 +// gas legacy: 97777 +// gas legacyOptimized: 91993 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol index 27fb9f0c5736..054d61c6772b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 -// gas irOptimized: 273543 -// gas legacy: 282601 -// gas legacyOptimized: 281510 +// gas irOptimized: 273548 +// gas legacy: 280148 +// gas legacyOptimized: 274502 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol index 980e414d1451..7ceadf481c66 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 -// gas irOptimized: 232995 -// gas legacy: 235694 -// gas legacyOptimized: 235193 +// gas irOptimized: 233012 +// gas legacy: 239400 +// gas legacyOptimized: 233948 diff --git a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol index becc3d4cdefd..a1849bd65fce 100644 --- a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol @@ -52,9 +52,9 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 149868 -// gas legacy: 150737 -// gas legacyOptimized: 148690 +// gas irOptimized: 149856 +// gas legacy: 156721 +// gas legacyOptimized: 149000 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol index 5d4e5b45e4a9..ffa0c68adcbe 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol @@ -38,10 +38,10 @@ contract c { // compileViaYul: true // ---- // test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 181029 +// gas irOptimized: 180918 // test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 // gas irOptimized: 157604 // test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 -// gas irOptimized: 134801 +// gas irOptimized: 134685 // test4(uint256[2][2]): 23, 42, 23, 42 -> 65 // gas irOptimized: 111177 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol index b892ec991ce3..933a1ab1b1c5 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol @@ -38,12 +38,14 @@ contract Test { } // ---- // test() -> 24 -// gas irOptimized: 226734 -// gas legacy: 227083 -// gas legacyOptimized: 226529 +// gas irOptimized: 226647 +// gas legacy: 229060 +// gas legacyOptimized: 226495 // test1() -> 3 // test2() -> 6 +// gas irOptimized: 95905 +// gas legacy: 100519 // test3() -> 24 -// gas irOptimized: 141319 -// gas legacy: 142238 -// gas legacyOptimized: 141365 +// gas irOptimized: 141297 +// gas legacy: 146668 +// gas legacyOptimized: 141331 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol index ab3c172d3399..e3b9cdaadcb9 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol @@ -45,7 +45,7 @@ contract C { } // ---- // copyExternalStorageArrayOfFunctionType() -> true -// gas irOptimized: 104566 -// gas legacy: 108554 -// gas legacyOptimized: 102405 +// gas irOptimized: 104629 +// gas legacy: 111170 +// gas legacyOptimized: 104620 // copyInternalArrayOfFunctionType() -> true diff --git a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol index d121b22d49ea..92b61b9291cd 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol @@ -49,7 +49,7 @@ contract C { // ---- // copyExternalStorageArraysOfFunctionType() -> true // gas irOptimized: 104238 -// gas legacy: 108295 -// gas legacyOptimized: 102162 +// gas legacy: 110911 +// gas legacyOptimized: 104377 // copyInternalArrayOfFunctionType() -> true -// gas legacy: 36192 +// gas legacy: 38695 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol index 3147401cfa1d..e4b3d14fd76b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol @@ -17,4 +17,4 @@ contract C { // compileViaYul: true // ---- // f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12 -// gas irOptimized: 120747 +// gas irOptimized: 120751 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol index 09037719a6f0..acc968389229 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol @@ -23,4 +23,4 @@ contract C { // compileViaYul: true // ---- // f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1 -// gas irOptimized: 327456 +// gas irOptimized: 327461 diff --git a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol index c5519e83aa43..667685c9c83f 100644 --- a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol @@ -37,8 +37,8 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 147755 -// gas legacy: 148892 -// gas legacyOptimized: 146917 +// gas irOptimized: 147749 +// gas legacy: 154218 +// gas legacyOptimized: 147020 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol index 93b541620ace..fea2c895d81c 100644 --- a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol @@ -11,8 +11,8 @@ contract Test { // ---- // set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18 // gas irOptimized: 95505 -// gas legacy: 103509 -// gas legacyOptimized: 101266 +// gas legacy: 104176 +// gas legacyOptimized: 96785 // data(uint256): 7 -> 8 // data(uint256): 15 -> 16 // data(uint256): 18 -> FAILURE diff --git a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol index 90012eed4c77..4ab381f4e614 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol @@ -5,17 +5,20 @@ contract c { } // ---- // set(uint256): 1, 2 -> true -// gas irOptimized: 110550 +// gas irOptimized: 110560 // gas legacy: 111310 // gas legacyOptimized: 110741 // set(uint256): 2, 2, 3, 4, 5 -> true -// gas irOptimized: 177501 +// gas irOptimized: 177511 // gas legacy: 178312 // gas legacyOptimized: 177716 // storageEmpty -> 0 // copy(uint256,uint256): 1, 2 -> true +// gas irOptimized: 48421 // storageEmpty -> 0 // copy(uint256,uint256): 99, 1 -> true +// gas irOptimized: 35641 // storageEmpty -> 0 // copy(uint256,uint256): 99, 2 -> true +// gas irOptimized: 35641 // storageEmpty -> 1 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 d00f5573a0af..37769cb4966c 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -19,23 +19,24 @@ contract c { // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 // gas irOptimized: 103268 // gas legacy: 112904 -// gas legacyOptimized: 112647 +// gas legacyOptimized: 112645 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 // gas irOptimized: 117825 // gas legacy: 128964 -// gas legacyOptimized: 128854 +// gas legacyOptimized: 128859 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 124091 -// gas legacy: 136092 -// gas legacyOptimized: 135469 +// gas irOptimized: 123888 +// gas legacy: 135510 +// gas legacyOptimized: 135218 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 127151 -// gas legacy: 148692 -// gas legacyOptimized: 148699 +// gas irOptimized: 126948 +// gas legacy: 148110 +// gas legacyOptimized: 148448 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 -// gas legacy: 59751 -// gas legacyOptimized: 57208 +// gas irOptimized: 54204 +// gas legacy: 59832 +// gas legacyOptimized: 57268 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 // gas irOptimized: 416918 // gas legacy: 458997 -// gas legacyOptimized: 460664 +// gas legacyOptimized: 460669 diff --git a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol index 3df22c725192..400834772869 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol @@ -9,6 +9,6 @@ contract C { } // ---- // f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1 -// gas irOptimized: 111084 -// gas legacy: 111548 -// gas legacyOptimized: 111321 +// gas irOptimized: 110973 +// gas legacy: 112436 +// gas legacyOptimized: 111313 diff --git a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol index e6284072d1f9..cdc3c4f66765 100644 --- a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol +++ b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol @@ -16,10 +16,10 @@ contract C { } // ---- // constructor() -// gas irOptimized: 90065 -// gas irOptimized code: 149000 -// gas legacy: 89553 -// gas legacy code: 126200 -// gas legacyOptimized: 83556 -// gas legacyOptimized code: 98200 +// gas irOptimized: 89349 +// gas irOptimized code: 140200 +// gas legacy: 100902 +// gas legacy code: 271400 +// gas legacyOptimized: 83062 +// gas legacyOptimized code: 91800 // f() -> 0 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 787973c5f0e5..9a68f88d8971 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 @@ -37,10 +37,11 @@ contract C { // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 // gas irOptimized: 179405 // gas legacy: 180675 -// gas legacyOptimized: 179686 +// gas legacyOptimized: 179690 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 106338 -// gas legacy: 109415 -// gas legacyOptimized: 106600 +// gas irOptimized: 106381 +// gas legacy: 109472 +// gas legacyOptimized: 106648 // h() -> 0x40, 0x60, 0x00, 0x00 +// gas irOptimized: 46948 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol index fc274bf47b28..caa0596610ad 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol @@ -46,6 +46,6 @@ contract C { } // ---- // f() -> 0xff -// gas irOptimized: 143857 -// gas legacy: 153404 -// gas legacyOptimized: 146676 +// gas irOptimized: 143935 +// gas legacy: 153487 +// gas legacyOptimized: 146748 diff --git a/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol index 7db82f891dfb..5fc981340942 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol @@ -15,6 +15,6 @@ contract C { } // ---- // test() -> 7 -// gas irOptimized: 122459 -// gas legacy: 205176 -// gas legacyOptimized: 204971 +// gas irOptimized: 122575 +// gas legacy: 208558 +// gas legacyOptimized: 202409 diff --git a/test/libsolidity/semanticTests/array/copying/copy_internal_function_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_internal_function_array_to_storage.sol index 95ba9d8ed8e8..6c1d061d309b 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_internal_function_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_internal_function_array_to_storage.sol @@ -18,6 +18,6 @@ contract C { } // ---- // one() -> 3 -// gas legacy: 140253 -// gas legacyOptimized: 140093 +// gas legacy: 142687 +// gas legacyOptimized: 135991 // two() -> FAILURE, hex"4e487b71", 0x51 diff --git a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol index 46216e912ce4..6872995d1cbb 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol @@ -9,7 +9,8 @@ contract c { // set(): 1, 2, 3, 4, 5 -> true // gas irOptimized: 177344 // gas legacy: 177953 -// gas legacyOptimized: 177550 +// gas legacyOptimized: 177551 // storageEmpty -> 0 // reset() -> true +// gas irOptimized: 47341 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol b/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol index ce4344e871db..d29feccf421c 100644 --- a/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol +++ b/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol @@ -18,13 +18,15 @@ contract sender { } // ---- // (): 7 -> -// gas irOptimized: 110822 +// gas irOptimized: 110735 // gas legacy: 111388 -// gas legacyOptimized: 111065 +// gas legacyOptimized: 111066 // val() -> 0 // forward(bool): true -> true +// gas irOptimized: 49573 // val() -> 0x80 // forward(bool): false -> true +// gas irOptimized: 31410 // val() -> 0x80 // forward(bool): true -> true // val() -> 0x80 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol index 672e7435f1a9..5c64ba63f8f8 100644 --- a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol @@ -31,8 +31,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 327921 +// gas irOptimized: 327936 // test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 141162 +// gas irOptimized: 141168 // test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 188442 +// gas irOptimized: 188448 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol index f232d8aba9d4..12c40849fe6f 100644 --- a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol @@ -31,8 +31,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 332567 +// gas irOptimized: 332582 // test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 145409 +// gas irOptimized: 145415 // test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 192248 +// gas irOptimized: 192254 diff --git a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol index 640046a11a4f..a5cf48011226 100644 --- a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol @@ -46,11 +46,11 @@ contract C { } // ---- // test() -> 0x20, 0x14, "[a called][b called]" -// gas irOptimized: 116518 -// gas legacy: 118841 -// gas legacyOptimized: 116843 +// gas irOptimized: 116512 +// gas legacy: 120226 +// gas legacyOptimized: 116941 // test2() -> 0x20, 0x14, "[b called][a called]" // test3() -> 0x20, 0x14, "[b called][a called]" -// gas irOptimized: 103144 -// gas legacy: 102654 -// gas legacyOptimized: 101556 +// gas irOptimized: 103138 +// gas legacy: 105192 +// gas legacyOptimized: 103752 diff --git a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol index 8a4d870b22f8..93eb84427d66 100644 --- a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol @@ -18,6 +18,6 @@ contract C { } // ---- // f() -> 3 -// gas irOptimized: 128296 -// gas legacy: 129077 -// gas legacyOptimized: 128210 +// gas irOptimized: 128301 +// gas legacy: 129528 +// gas legacyOptimized: 128171 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol index 89eeb27dcef2..f9d14b59edf5 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol @@ -26,4 +26,4 @@ contract C { // test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 // test2(uint8[2][2]): 1, 2, 3, 4 // gas irOptimized: 72076 -// gas legacyOptimized: 95103 +// gas legacyOptimized: 72086 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol index bd74ae0158e2..d604a11e6cd4 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol @@ -26,4 +26,4 @@ contract C { // test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 // test2(uint8[2][2]): 1, 2, 3, 4 // gas irOptimized: 73031 -// gas legacyOptimized: 96288 +// gas legacyOptimized: 73155 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol index f3934fec0f6f..1a3fb70e0845 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol @@ -71,14 +71,14 @@ contract C { // ---- // test1() -> // gas irOptimized: 150488 -// gas legacy: 150949 -// gas legacyOptimized: 150906 +// gas legacy: 156275 +// gas legacyOptimized: 151018 // test2() -> FAILURE // gas irOptimized: 150389 -// gas legacy: 150672 -// gas legacyOptimized: 150575 +// gas legacy: 155998 +// gas legacyOptimized: 150684 // test3() -> // gas irOptimized: 124300 -// gas legacy: 125333 -// gas legacyOptimized: 125127 +// gas legacy: 130649 +// gas legacyOptimized: 125142 // test4() -> FAILURE diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol index 7621b2477e03..b27fe9e06453 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 304788 +// gas irOptimized: 304750 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 116653 +// gas irOptimized: 116659 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 187994 +// gas irOptimized: 187942 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol index 8ec3f77691b5..146de2f2af6a 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 309072 +// gas irOptimized: 309034 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 118314 +// gas irOptimized: 118320 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 191045 +// gas irOptimized: 190993 diff --git a/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol index 57b3dc521f65..7583f5ab4f0d 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol @@ -30,7 +30,7 @@ contract C { // compileViaYul: true // ---- // test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -// gas irOptimized: 137897 +// gas irOptimized: 137891 // test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -// gas irOptimized: 164482 +// gas irOptimized: 164249 // gas legacyOptimized: 120228 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 e5a6ae53b2da..3f52085f4b34 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -13,4 +13,4 @@ contract C { // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 // gas irOptimized: 202083 // gas legacy: 204327 -// gas legacyOptimized: 202899 +// gas legacyOptimized: 202903 diff --git a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol index f776626ae8e3..03c47f69b414 100644 --- a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol +++ b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol @@ -16,6 +16,6 @@ contract c { } // ---- // test1() -> true -// gas irOptimized: 218449 +// gas irOptimized: 218420 // gas legacy: 242263 -// gas legacyOptimized: 241182 +// gas legacyOptimized: 241187 diff --git a/test/libsolidity/semanticTests/array/delete/delete_bytes_array.sol b/test/libsolidity/semanticTests/array/delete/delete_bytes_array.sol index b735d182d555..32a96c72c310 100644 --- a/test/libsolidity/semanticTests/array/delete/delete_bytes_array.sol +++ b/test/libsolidity/semanticTests/array/delete/delete_bytes_array.sol @@ -32,3 +32,4 @@ contract C { // ---- // f() -> 0 // g() -> 0 +// gas irOptimized: 56617 diff --git a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol index f486a50cfafe..23b0466e7530 100644 --- a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol +++ b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol @@ -14,6 +14,6 @@ contract C { } // ---- // f() -> 0, 0, 0 -// gas irOptimized: 88026 -// gas legacy: 88800 -// gas legacyOptimized: 87700 +// gas irOptimized: 88028 +// gas legacy: 88799 +// gas legacyOptimized: 87706 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index b4ba8b47fdba..af0ec6b7faf0 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -15,7 +15,7 @@ contract c { // gas legacyOptimized: 466238 // storageEmpty -> 0 // clear() -> -// gas irOptimized: 97705 -// gas legacy: 97919 -// gas legacyOptimized: 97790 +// gas irOptimized: 97800 +// gas legacy: 97947 +// gas legacyOptimized: 97882 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol b/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol index 95df74b4d77b..a53d00eaaf31 100644 --- a/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol +++ b/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol @@ -40,16 +40,18 @@ contract C { // copyFromStorageShort() // x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 // copyFromStorageLong() -// gas irOptimized: 121095 +// gas irOptimized: 121092 // gas legacy: 121904 -// gas legacyOptimized: 121388 +// gas legacyOptimized: 121393 // x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 // copyToStorage() // x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 // y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 // del() +// gas irOptimized: 29404 // x() -> 0x20, 0x00 // invalidateXLong() +// gas irOptimized: 47028 // x() -> FAILURE, hex"4e487b71", 0x22 // abiEncode() -> FAILURE, hex"4e487b71", 0x22 // abiEncodePacked() -> FAILURE, hex"4e487b71", 0x22 diff --git a/test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_delete.sol b/test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_delete.sol new file mode 100644 index 000000000000..b638664aaca1 --- /dev/null +++ b/test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_delete.sol @@ -0,0 +1,77 @@ +contract C { + bytes testArray; + + struct Canary { + uint256 value; + } + + function getCanary() internal pure returns (Canary storage canary) { + assembly { + mstore(0, testArray.slot) + let testArrayDataArea := keccak256(0, 0x20) + // testArray's data area occupies 3 slots when filled. Canary goes right after + canary.slot := add(testArrayDataArea, 3) + } + } + + constructor() { + Canary storage canary = getCanary(); + canary.value = type(uint256).max; + } + + function getArrayDataAreaSlot() public pure returns (uint256 slot) { + assembly { + mstore(0, testArray.slot) + slot := keccak256(0, 0x20) + } + assert(slot == 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563); + return slot; + } + + function getCanarySlot() public pure returns (uint256) { + return getArrayDataAreaSlot() + 3; + } + + function checkSlots() public view returns (uint256, uint256, uint256, uint256, uint256) { + uint256 dataSlot = getArrayDataAreaSlot(); + uint256 slot0; + uint256 slot1; + uint256 slot2; + uint256 slot3; + assembly { + slot0 := sload(dataSlot) + slot1 := sload(add(dataSlot, 1)) + slot2 := sload(add(dataSlot, 2)) + slot3 := sload(add(dataSlot, 3)) + } + return (slot0, slot1, slot2, slot3, testArray.length); + } + + function fillArray() public { + // Fill testArray to exactly 96 bytes (3 slots in its data area) + for (uint i = 0; i < 96; i++) { + testArray.push(bytes1(uint8(i + 1))); + } + } + + function deleteArray() public { + // Should clear 3 slots without touching canary + delete testArray; + } + + function canaryValue() public view returns (uint256) { + return getCanary().value; + } +} +// ---- +// getArrayDataAreaSlot() -> 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 +// getCanarySlot() -> 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566 +// checkSlots() -> 0, 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// fillArray() +// gas irOptimized: 197289 +// gas legacy: 220574 +// gas legacyOptimized: 206839 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// deleteArray() +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_overwrite_with_long.sol b/test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_overwrite_with_long.sol new file mode 100644 index 000000000000..edb00809bcd3 --- /dev/null +++ b/test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_overwrite_with_long.sol @@ -0,0 +1,105 @@ +contract C { + bytes testArray; + + struct Canary { + uint256 value; + } + + function getCanary() internal pure returns (Canary storage canary) { + assembly { + mstore(0, testArray.slot) + let testArrayDataArea := keccak256(0, 0x20) + // testArray's data area occupies 3 slots when filled. Canary goes right after + canary.slot := add(testArrayDataArea, 3) + } + } + + constructor() { + Canary storage canary = getCanary(); + canary.value = type(uint256).max; // Should not be overwritten + } + + function fillArray() public { + // Fill testArray to exactly 96 bytes (3 slots in its data area) + for (uint i = 0; i < 96; i++) { + testArray.push(bytes1(uint8(i + 1))); + } + } + + function shrinkArray() public returns (uint256) { + // Shrink from 96 to 50 bytes. Should clear slot 2 without touching canary + bytes memory newData = new bytes(50); + for (uint i = 0; i < 50; i++) { + newData[i] = bytes1(uint8(i + 2)); + } + testArray = newData; + return testArray.length; + } + + function canaryValue() public view returns (uint256) { + return getCanary().value; + } + + function arrayLength() public view returns (uint256) { + return testArray.length; + } + + function getDataSlotContent(uint256 index) public view returns (bytes32 value) { + assembly { + mstore(0, testArray.slot) + let testArrayDataArea := keccak256(0, 0x20) + let slot := add(testArrayDataArea, index) + value := sload(slot) + } + return value; + } + + function checkSlots() public view returns (bytes32, bytes32, bytes32, uint256, uint256) { + return ( + getDataSlotContent(0), // First data slot + getDataSlotContent(1), // Second data slot (partial cleanup expected) + getDataSlotContent(2), // Third data slot (should be cleared after shrink) + canaryValue(), // Canary value (should never change) + arrayLength() // Current array length + ); + } + + function getSlot1LastBytes() public view returns (bytes14 lastBytes) { + // Get the last 14 bytes of slot 1, which should be zero after partial cleanup + bytes32 slot1 = getDataSlotContent(1); + assembly { + // Shift left by 18 bytes (144 bits) to move the last 14 bytes to the front + lastBytes := shl(144, slot1) + } + return lastBytes; + } + + function getArrayBytes(uint256 start, uint256 count) public view returns (bytes memory) { + bytes memory result = new bytes(count); + for (uint i = 0; i < count && start + i < testArray.length; i++) { + result[i] = testArray[start + i]; + } + return result; + } +} +// ---- +// arrayLength() ->0 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// fillArray() +// gas irOptimized: 197352 +// gas legacy: 220574 +// gas legacyOptimized: 206839 +// arrayLength() ->96 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getArrayBytes(uint256,uint256): 0, 5 -> 0x20, 5, 0x0102030405000000000000000000000000000000000000000000000000000000 +// getArrayBytes(uint256,uint256): 32, 5 -> 0x20, 5, 0x2122232425000000000000000000000000000000000000000000000000000000 +// getArrayBytes(uint256,uint256): 64, 5 -> 0x20, 5, 0x4142434445000000000000000000000000000000000000000000000000000000 +// shrinkArray() -> 50 +// arrayLength() ->50 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getArrayBytes(uint256,uint256): 0, 5 -> 0x20, 5, 0x0203040506000000000000000000000000000000000000000000000000000000 +// getArrayBytes(uint256,uint256): 32, 5 -> 0x20, 5, 0x2223242526000000000000000000000000000000000000000000000000000000 +// getArrayBytes(uint256,uint256): 45, 5 -> 0x20, 5, 0x2f30313233000000000000000000000000000000000000000000000000000000 +// getSlot1LastBytes() -> 0 +// getDataSlotContent(uint256): 2 -> 0 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/test/libsolidity/semanticTests/array/nested_calldata_storage2.sol b/test/libsolidity/semanticTests/array/nested_calldata_storage2.sol index f8db31b54cc8..f3cb51187103 100644 --- a/test/libsolidity/semanticTests/array/nested_calldata_storage2.sol +++ b/test/libsolidity/semanticTests/array/nested_calldata_storage2.sol @@ -8,6 +8,6 @@ contract C { // compileViaYul: true // ---- // i(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -// gas irOptimized: 245506 +// gas irOptimized: 245511 // tmp_i(uint256,uint256): 0, 0 -> 0x0A01 // tmp_i(uint256,uint256): 1, 0 -> 0x0B01 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol index 96fb11a2dc94..3b96397166ea 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol @@ -23,7 +23,7 @@ contract c { } // ---- // test() -> 1, 2, 3 -// gas irOptimized: 1828226 -// gas legacy: 1822464 -// gas legacyOptimized: 1813404 +// gas irOptimized: 1828383 +// gas legacy: 1841995 +// gas legacyOptimized: 1821687 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol index 77ae8c4e23e4..83c5c1724307 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol @@ -13,5 +13,5 @@ contract C { // ---- // f(uint120[]): 0x20, 3, 1, 2, 3 -> 1 // gas irOptimized: 112852 -// gas legacy: 113657 -// gas legacyOptimized: 113465 +// gas legacy: 114404 +// gas legacyOptimized: 113087 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct.sol b/test/libsolidity/semanticTests/array/push/array_push_struct.sol index 92f071e1fb22..4e1e8b4b3db0 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct.sol @@ -21,5 +21,5 @@ contract c { // ---- // test() -> 2, 3, 4, 5 // gas irOptimized: 135329 -// gas legacy: 147437 -// gas legacyOptimized: 146429 +// gas legacy: 139481 +// gas legacyOptimized: 135795 diff --git a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol index 5633199d4865..04b2a4a736c9 100644 --- a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol +++ b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol @@ -15,4 +15,4 @@ contract C { // f() -> // gas irOptimized: 179534 // gas legacy: 181013 -// gas legacyOptimized: 180397 +// gas legacyOptimized: 180406 diff --git a/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol b/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol index 33ab18450624..c3f2e8d751e5 100644 --- a/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol @@ -11,7 +11,8 @@ contract c { // (): 1, 2, 3, 4, 5 -> // gas irOptimized: 155122 // gas legacy: 155473 -// gas legacyOptimized: 155295 +// gas legacyOptimized: 155296 // checkIfDataIsEmpty() -> false // sendMessage() -> true, 0x40, 0 +// gas irOptimized: 41925 // checkIfDataIsEmpty() -> true diff --git a/test/libsolidity/semanticTests/cleanup/byte_array_to_storage_cleanup.sol b/test/libsolidity/semanticTests/cleanup/byte_array_to_storage_cleanup.sol index 238f96b7e588..4c75ad452b8d 100644 --- a/test/libsolidity/semanticTests/cleanup/byte_array_to_storage_cleanup.sol +++ b/test/libsolidity/semanticTests/cleanup/byte_array_to_storage_cleanup.sol @@ -28,13 +28,14 @@ contract C { // compileViaYul: also // ---- // constructor() -> -// gas irOptimized: 82100 -// gas irOptimized code: 357600 -// gas legacy: 101532 -// gas legacy code: 604800 -// gas legacyOptimized: 84956 -// gas legacyOptimized code: 391800 +// gas irOptimized: 82586 +// gas irOptimized code: 363600 +// gas legacy: 101811 +// gas legacy code: 608200 +// gas legacyOptimized: 85196 +// gas legacyOptimized code: 394800 // h() -> 0x20, 0x40, 0x00, 0 // ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00 // g() -> 0x20, 0x40, 0, 0x00 // f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000 +// gas irOptimized: 54117 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index aeeb1a0c1aa4..76a4dd961fe4 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -28,7 +28,7 @@ contract Creator { // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 // gas irOptimized: 327784 // gas irOptimized code: 94000 -// gas legacy: 336623 +// gas legacy: 338477 // gas legacy code: 244800 -// gas legacyOptimized: 329515 +// gas legacyOptimized: 329166 // gas legacyOptimized code: 117000 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 55abe4804c56..91be8e3789f3 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -26,9 +26,9 @@ contract Creator { // bytecodeFormat: legacy,>=EOFv1 // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 169292 +// gas irOptimized: 169297 // gas irOptimized code: 99600 -// gas legacy: 172941 +// gas legacy: 172946 // gas legacy code: 239800 -// gas legacyOptimized: 169815 +// gas legacyOptimized: 169823 // gas legacyOptimized code: 118600 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index 13db633b9b06..8a072f3ebed6 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -10,11 +10,11 @@ contract Test { // bytecodeFormat: legacy,>=EOFv1 // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> -// gas irOptimized: 181465 +// gas irOptimized: 181629 // gas irOptimized code: 78400 -// gas legacy: 195212 +// gas legacy: 195484 // gas legacy code: 109400 -// gas legacyOptimized: 181608 +// gas legacyOptimized: 181853 // gas legacyOptimized code: 71400 // m_x() -> 7 // m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" diff --git a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol index ed4eb6e4d15f..cc196a95c802 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol @@ -13,9 +13,9 @@ contract C { // constructor(): 1, 2, 3, 4 -> // gas irOptimized: 148129 // gas irOptimized code: 23000 -// gas legacy: 157977 +// gas legacy: 166201 // gas legacy code: 60400 -// gas legacyOptimized: 149973 +// gas legacyOptimized: 149177 // gas legacyOptimized code: 26200 // a() -> 1 // b(uint256): 0 -> 2 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol index 1ff58d65b566..42b9b50dd779 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol @@ -16,5 +16,5 @@ contract C { // createEvent(uint256): 42 -> // ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d // gas irOptimized: 185148 -// gas legacy: 187493 +// gas legacy: 188615 // gas legacyOptimized: 184548 diff --git a/test/libsolidity/semanticTests/fallback/call_forward_bytes.sol b/test/libsolidity/semanticTests/fallback/call_forward_bytes.sol index 7bf3aee3acfe..dfd3d658fe2f 100644 --- a/test/libsolidity/semanticTests/fallback/call_forward_bytes.sol +++ b/test/libsolidity/semanticTests/fallback/call_forward_bytes.sol @@ -20,6 +20,7 @@ contract sender { // forward() -> true // val() -> 8 // clear() -> true +// gas irOptimized: 29243 // val() -> 8 // forward() -> true // val() -> 0x80 diff --git a/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol b/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol index 8a795373e061..8d72f7c04358 100644 --- a/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol +++ b/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol @@ -22,11 +22,12 @@ contract Test { // set(bytes): 0x20, 0 // storageEmpty -> 1 // set(bytes): 0x20, 66, "12345678901234567890123456789012", "12345678901234567890123456789012", "12" -// gas irOptimized: 111849 +// gas irOptimized: 111820 // gas legacy: 112734 -// gas legacyOptimized: 112084 +// gas legacyOptimized: 112089 // storageEmpty -> 0 // set(bytes): 0x20, 3, "abc" +// gas irOptimized: 33989 // storageEmpty -> 0 // set(bytes): 0x20, 0 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/storage/static_array_copy_cleanup.sol b/test/libsolidity/semanticTests/storage/static_array_copy_cleanup.sol new file mode 100644 index 000000000000..ca471161d5e2 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/static_array_copy_cleanup.sol @@ -0,0 +1,94 @@ +contract C { + struct S { + uint64 a; + uint64 b; + uint64 c; + uint64 d; + // All fit in one slot (4 * 64 = 256 bits) + } + + S[5] source; + S[10] dest; + uint256 public canary = type(uint256).max; + + function fillSource() public { + for (uint i = 0; i < 5; i++) { + source[i] = S({ + a: uint64(1 + i * 4), + b: uint64(2 + i * 4), + c: uint64(3 + i * 4), + d: uint64(4 + i * 4) + }); + } + } + + function fillDest() public { + for (uint i = 0; i < 10; i++) { + dest[i] = S({ + a: uint64(100 + i * 4), + b: uint64(101 + i * 4), + c: uint64(102 + i * 4), + d: uint64(103 + i * 4) + }); + } + } + + function copySourceToDest() public { + dest = source; + } + + function deleteSource() public { + delete source; + } + + function deleteDest() public { + delete dest; + } + + function getSourceAsUint() public view returns (uint64[20] memory result) { + for (uint i = 0; i < 5; i++) { + result[i * 4] = source[i].a; + result[i * 4 + 1] = source[i].b; + result[i * 4 + 2] = source[i].c; + result[i * 4 + 3] = source[i].d; + } + } + + function getDestAsUint() public view returns (uint64[40] memory result) { + for (uint i = 0; i < 10; i++) { + result[i * 4] = dest[i].a; + result[i * 4 + 1] = dest[i].b; + result[i * 4 + 2] = dest[i].c; + result[i * 4 + 3] = dest[i].d; + } + } +} +// ---- +// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getSourceAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// getDestAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// fillSource() +// gas irOptimized: 135018 +// gas legacy: 146851 +// gas legacyOptimized: 137549 +// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getSourceAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 +// fillDest() +// gas irOptimized: 248706 +// gas legacy: 272468 +// gas legacyOptimized: 253871 +// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getSourceAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 +// getDestAsUint() -> 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139 +// copySourceToDest() +// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getSourceAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 +// getDestAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// deleteSource() +// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getSourceAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// getDestAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// deleteDest() +// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// getSourceAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// getDestAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_array_and_partial_assignment_with_layout.sol b/test/libsolidity/semanticTests/storage/storage_boundary_array_and_partial_assignment_with_layout.sol new file mode 100644 index 000000000000..1e2637c851f9 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_array_and_partial_assignment_with_layout.sol @@ -0,0 +1,54 @@ +contract C layout at 2**256 - 5 { + uint256 a; + + function getArray() internal pure returns (uint256[10][1] storage _x) { + assembly { + _x.slot := a.slot + } + } + + function fillArray() public { + uint256[10][1] storage _x = getArray(); + for (uint i = 1; i < 10; i++) + _x[0][i] = i; + } + + function partialAssignArrayBeforeStorageBoundary() public { + uint256[10][1] storage _x = getArray(); + _x[0] = [11, 12, 13]; + } + + function partialAssignArrayCrossStorageBoundary() public { + uint256[10][1] storage _x = getArray(); + _x[0] = [14, 15, 16, 17, 18, 19, 20]; + } + + function clearArray() public { + uint256[10][1] storage _x = getArray(); + delete _x[0]; + } + + function x() public view returns (uint256[10] memory) { + return getArray()[0]; + } +} +// ---- +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// fillArray() +// gas irOptimized: 220749 +// gas legacy: 221473 +// gas legacyOptimized: 220915 +// partialAssignArrayBeforeStorageBoundary() +// x() -> 11, 12, 13, 0, 0, 0, 0, 0, 0, 0 +// fillArray() +// gas irOptimized: 186549 +// gas legacy: 187273 +// gas legacyOptimized: 186715 +// x() -> 11, 1, 2, 3, 4, 5, 6, 7, 8, 9 +// partialAssignArrayCrossStorageBoundary() +// x() -> 14, 15, 16, 17, 18, 19, 20, 0, 0, 0 +// clearArray() +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 44183 +// gas legacy: 46007 +// gas legacyOptimized: 43907 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_array_assignment.sol b/test/libsolidity/semanticTests/storage/storage_boundary_array_assignment.sol new file mode 100644 index 000000000000..0de66a71472f --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_array_assignment.sol @@ -0,0 +1,28 @@ +contract C { + function getArray() internal pure returns (uint256[10][1] storage _x) { + assembly { + _x.slot := sub(0, 5) + } + } + + function assignArray(uint256[10] memory y) public { + uint256[10][1] storage _x = getArray(); + _x[0] = y; + } + + function x() public view returns (uint256[10] memory) { + return getArray()[0]; + } +} +// ---- +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// assignArray(uint256[10]): 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> +// gas irOptimized: 245236 +// gas legacy: 249351 +// gas legacyOptimized: 245365 +// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +// assignArray(uint256[10]): 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 -> +// x() -> 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 +// gas irOptimized: 44183 +// gas legacy: 46012 +// gas legacyOptimized: 43907 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_array_copy.sol b/test/libsolidity/semanticTests/storage/storage_boundary_array_copy.sol new file mode 100644 index 000000000000..949edc4907eb --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_array_copy.sol @@ -0,0 +1,61 @@ +contract C { + constructor() { + uint256[10][1] storage _x = getX(); + _x[0] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + } + + function getX() internal pure returns (uint256[10][1] storage _x) { + assembly { + _x.slot := sub(0, 5) + } + } + + function getY() internal pure returns (uint256[10][1] storage _y) { + assembly { + _y.slot := 5 + } + } + + function copyXToY() public { + uint256[10][1] storage _x = getX(); + uint256[10][1] storage _y = getY(); + _y[0] = _x[0]; + } + + function clearX() public { + uint256[10][1] storage _x = getX(); + delete _x[0]; + } + + function copyYToX() public { + uint256[10][1] storage _x = getX(); + uint256[10][1] storage _y = getY(); + _x[0] = _y[0]; + } + + function x() public view returns (uint256[10] memory) { + return getX()[0]; + } + + function y() public view returns (uint256[10] memory) { + return getY()[0]; + } +} +// ---- +// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +// y() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// copyXToY() +// gas irOptimized: 264224 +// gas legacy: 265434 +// gas legacyOptimized: 264247 +// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +// y() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +// clearX() +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// y() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +// copyYToX() +// gas irOptimized: 266243 +// gas legacy: 267456 +// gas legacyOptimized: 266280 +// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +// y() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_array_delete.sol b/test/libsolidity/semanticTests/storage/storage_boundary_array_delete.sol new file mode 100644 index 000000000000..20d2e2ec9df5 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_array_delete.sol @@ -0,0 +1,34 @@ +contract C { + function getArray() internal pure returns (uint256[10][1] storage _x) { + assembly { + _x.slot := sub(0, 5) + } + } + + function fillArray() public { + uint256[10][1] storage _x = getArray(); + for (uint i = 1; i < 10; i++) + _x[0][i] = i; + } + + function clearArray() public { + uint256[10][1] storage _x = getArray(); + delete _x[0]; + } + + function x() public view returns (uint256[10] memory) { + return getArray()[0]; + } +} +// ---- +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// fillArray() +// gas irOptimized: 220705 +// gas legacy: 221434 +// gas legacyOptimized: 220871 +// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 +// clearArray() +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 44183 +// gas legacy: 46012 +// gas legacyOptimized: 43907 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_array_delete_overlapping_variable.sol b/test/libsolidity/semanticTests/storage/storage_boundary_array_delete_overlapping_variable.sol new file mode 100644 index 000000000000..3bb605cc919e --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_array_delete_overlapping_variable.sol @@ -0,0 +1,40 @@ +contract C { + uint256 public y = 42; + + function getArray() internal pure returns (uint256[10][1] storage _x) { + assembly { + _x.slot := sub(0, 5) + } + } + + function fillArray() public { + uint256[10][1] storage _x = getArray(); + for (uint i = 1; i < 10; i++) + _x[0][i] = i; + } + + function clearArray() public { + uint256[10][1] storage _x = getArray(); + delete _x[0]; + } + + function x() public view returns (uint256[10] memory) { + return getArray()[0]; + } +} + +// ---- +// y() -> 42 +// x() -> 0, 0, 0, 0, 0, 42, 0, 0, 0, 0 +// fillArray() +// gas irOptimized: 203627 +// gas legacy: 204356 +// gas legacyOptimized: 203793 +// y() -> 5 +// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 +// clearArray() +// y() -> 0 +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 44183 +// gas legacy: 46012 +// gas legacyOptimized: 43907 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_array_packing_not_overlapping_variable.sol b/test/libsolidity/semanticTests/storage/storage_boundary_array_packing_not_overlapping_variable.sol new file mode 100644 index 000000000000..77a6158acc84 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_array_packing_not_overlapping_variable.sol @@ -0,0 +1,63 @@ +contract C { + struct Canary { + uint256 value; + } + + constructor() { + Canary storage canary = getCanary(); + canary.value = type(uint256).max; // Should not be overwritten + } + + function getArray() internal pure returns (uint64[10][1] storage _x) { + // Array of 10 * uint64 values (8 bytes each) + // Packs 4 uint64 per slot -> 3 slots total (slots -1, 0, 1) + assembly { + _x.slot := sub(0, 1) + } + } + + function getCanary() internal pure returns (Canary storage canary) { + // Canary at slot 2, right after the array ends at slot 1 + assembly { + canary.slot := 2 + } + } + + function fillArray() public { + uint64[10][1] storage _x = getArray(); + for (uint64 i = 0; i < 10; i++) + _x[0][i] = i; + } + + function shrinkTo5() public { + uint64[10][1] storage _x = getArray(); + // Resize by assigning a smaller array + // This should clear items [5..9] without touching y + _x[0] = [uint64(11), 12, 13, 14, 15]; + } + + function clearArray() public { + uint64[10][1] storage _x = getArray(); + delete _x[0]; + } + + function x() public view returns (uint64[10] memory) { + return getArray()[0]; + } + + function canaryValue() public view returns (uint256) { + return getCanary().value; + } +} +// ---- +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// fillArray() +// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// shrinkTo5() +// x() -> 11, 12, 13, 14, 15, 0, 0, 0, 0, 0 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// clearArray() +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_array_partial_assignment.sol b/test/libsolidity/semanticTests/storage/storage_boundary_array_partial_assignment.sol new file mode 100644 index 000000000000..c4e3ee7794c0 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_array_partial_assignment.sol @@ -0,0 +1,41 @@ +contract C { + function getArray() internal pure returns (uint256[10][1] storage _x) { + assembly { + _x.slot := sub(0, 5) + } + } + + function fillArray() public { + uint256[10][1] storage _x = getArray(); + for (uint i = 1; i < 10; i++) + _x[0][i] = i; + } + + function x() public view returns (uint256[10] memory) { + return getArray()[0]; + } + + function partialAssignArrayBeforeStorageBoundary() public { + uint256[10][1] storage _x = getArray(); + _x[0] = [21, 22, 23]; + } + + function partialAssignArrayCrossStorageBoundary() public { + uint256[10][1] storage _x = getArray(); + _x[0] = [11, 12, 13, 14, 15, 16, 17]; + } +} +// ---- +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// fillArray() +// gas irOptimized: 220727 +// gas legacy: 221456 +// gas legacyOptimized: 220893 +// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 +// partialAssignArrayCrossStorageBoundary() +// x() -> 11, 12, 13, 14, 15, 16, 17, 0, 0, 0 +// partialAssignArrayBeforeStorageBoundary() +// x() -> 21, 22, 23, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 44183 +// gas legacy: 46012 +// gas legacyOptimized: 43907 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_delete_overflow_bug.sol b/test/libsolidity/semanticTests/storage/storage_boundary_delete_overflow_bug.sol new file mode 100644 index 000000000000..3ffb7774710a --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_delete_overflow_bug.sol @@ -0,0 +1,80 @@ +contract C { + mapping(string => uint256[256][2**240]) m; + + function getSlot() internal view returns (uint256) { + uint256[256][2**240] storage _x = m["v 2.2.3"]; + uint256 slot; + assembly { + slot := _x.slot + } + assert(slot == 0xffdb3f1d9f54eb0b5012935c286c508459d381405d269e01c15f4ec2826edbbf); + return slot; + } + + function getIndex() internal view returns (uint256) { + uint256 slot = getSlot(); + // Pick the largest index such that `slot + 256 * index` <= `2**256 - 1` + uint256 index = (type(uint256).max - slot) / 256; + assert(index <= type(uint240).max); + assert((type(uint256).max - slot + 1) % 256 != 0); + + return index; + } + + function getArray() internal view returns (uint256[256][2**240] storage _x) { + uint256 s = getSlot(); + assembly { + _x.slot := s + } + } + + function fillArray() public { + uint256[256][2**240] storage _x = getArray(); + for (uint i = 1; i < 256; i++) + _x[getIndex()][i] = i; + } + + function partialAssignArray() public { + uint256[256][2**240] storage _x = getArray(); + _x[getIndex()] = [11, 22, 33, 44, 55, 66, 77, 88, 99]; + } + + function clearArray() public { + uint256[256][2**240] storage _x = getArray(); + delete _x[getIndex()]; + } + + function x() public view returns (uint256[256] memory) { + return getArray()[getIndex()]; + } +} + +// ---- +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 604108 +// gas legacy: 644983 +// gas legacyOptimized: 598016 +// fillArray() +// gas irOptimized: 5782148 +// gas legacy: 6044562 +// gas legacyOptimized: 5853893 +// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 +// gas irOptimized: 604108 +// gas legacy: 644983 +// gas legacyOptimized: 598016 +// partialAssignArray() +// gas irOptimized: 1067376 +// gas legacy: 1177356 +// gas legacyOptimized: 1068067 +// x() -> 11, 22, 33, 44, 55, 66, 77, 88, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 604108 +// gas legacy: 644983 +// gas legacyOptimized: 598016 +// clearArray() +// gas irOptimized: 580378 +// gas legacy: 582976 +// gas legacyOptimized: 581290 +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 604108 +// gas legacy: 644983 +// gas legacyOptimized: 598016 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_packed_array.sol b/test/libsolidity/semanticTests/storage/storage_boundary_packed_array.sol new file mode 100644 index 000000000000..aa30a2bcac49 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_packed_array.sol @@ -0,0 +1,35 @@ +contract C { + function getArray() internal pure returns (uint64[40][1] storage _x) { + assembly { + _x.slot := sub(0, 5) + } + } + + function fillArray() public { + uint64[40][1] storage _x = getArray(); + for (uint64 i = 1; i < 40; i++) + _x[0][i] = i; + } + + function clearArray() public { + uint64[40][1] storage _x = getArray(); + delete _x[0]; + } + + function x() public view returns (uint64[40] memory) { + return getArray()[0]; + } +} +// ---- +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// fillArray() +// gas irOptimized: 254227 +// gas legacy: 258712 +// gas legacyOptimized: 257258 +// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 +// clearArray() +// gas irOptimized: 57426 +// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 48087 +// gas legacy: 64080 +// gas legacyOptimized: 56602 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_mixed_types.sol b/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_mixed_types.sol new file mode 100644 index 000000000000..213dee1dae23 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_mixed_types.sol @@ -0,0 +1,172 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256 a; // slot 0 (bytes 0-31) + uint128 b; // slot 1 (bytes 0-15) + uint64 c; // slot 1 (bytes 16-23) + bytes32 d; // slot 2 (bytes 0-31) + bool e; // slot 3 (byte 0) + // Total: 4 slots per struct + } + + struct Canary { + uint256 value; + } + + function getBoundaryArray() internal pure returns (S[10][1] storage arr) { + // 10 structs * 4 slots = 40 slots total + // Starts at -20, ends at slot 19 + assembly { + arr.slot := sub(0, 20) + } + } + + function getDest() internal pure returns (S[10][1] storage arr) { + assembly { + arr.slot := 21 + } + } + + function getCanary() internal pure returns (Canary storage canary) { + // Array ends at slot 19, canary at slot 20 + assembly { + canary.slot := 20 + } + } + + constructor() { + Canary storage canary = getCanary(); + canary.value = type(uint256).max; + } + + function fillBoundaryArray() public { + S[10][1] storage arr = getBoundaryArray(); + for (uint i = 0; i < 10; i++) { + arr[0][i] = S({ + a: 1 + i * 5, + b: uint128(2 + i * 5), + c: uint64(3 + i * 5), + d: bytes32(uint256(4 + i * 5)), + e: true + }); + } + } + + function deleteBoundaryArray() public { + S[10][1] storage arr = getBoundaryArray(); + delete arr[0]; + } + + function copyFromBoundary() public { + S[10][1] storage source = getBoundaryArray(); + S[10][1] storage dest = getDest(); + dest[0] = source[0]; + } + + function copyToBoundary() public { + S[10][1] storage source = getDest(); + S[10][1] storage dest = getBoundaryArray(); + dest[0] = source[0]; + } + + function fillDestArray() public { + S[10][1] storage dest = getDest(); + for (uint i = 0; i < 10; i++) { + dest[0][i] = S({ + a: 51 + i * 5, + b: uint128(52 + i * 5), + c: uint64(53 + i * 5), + d: bytes32(uint256(54 + i * 5)), + e: true + }); + } + } + + function boundaryArray() public view returns (S[10] memory) { + return getBoundaryArray()[0]; + } + + function destArray() public view returns (S[10] memory) { + return getDest()[0]; + } + + function canaryValue() public view returns (uint256) { + return getCanary().value; + } +} +// ---- +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 113169 +// gas legacy: 120742 +// gas legacyOptimized: 112518 +// destArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 113078 +// gas legacy: 120738 +// gas legacyOptimized: 112505 +// fillBoundaryArray() +// gas irOptimized: 912522 +// gas legacy: 930728 +// gas legacyOptimized: 916628 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, true, 6, 7, 8, 9, true, 11, 12, 13, 14, true, 16, 17, 18, 19, true, 21, 22, 23, 24, true, 26, 27, 28, 29, true, 31, 32, 33, 34, true, 36, 37, 38, 39, true, 41, 42, 43, 44, true, 46, 47, 48, 49, true +// gas irOptimized: 113169 +// gas legacy: 120742 +// gas legacyOptimized: 112518 +// destArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 113078 +// gas legacy: 120738 +// gas legacyOptimized: 112505 +// copyFromBoundary() +// gas irOptimized: 994579 +// gas legacy: 1023407 +// gas legacyOptimized: 994746 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, true, 6, 7, 8, 9, true, 11, 12, 13, 14, true, 16, 17, 18, 19, true, 21, 22, 23, 24, true, 26, 27, 28, 29, true, 31, 32, 33, 34, true, 36, 37, 38, 39, true, 41, 42, 43, 44, true, 46, 47, 48, 49, true +// gas irOptimized: 113169 +// gas legacy: 120742 +// gas legacyOptimized: 112518 +// destArray() -> 1, 2, 3, 4, true, 6, 7, 8, 9, true, 11, 12, 13, 14, true, 16, 17, 18, 19, true, 21, 22, 23, 24, true, 26, 27, 28, 29, true, 31, 32, 33, 34, true, 36, 37, 38, 39, true, 41, 42, 43, 44, true, 46, 47, 48, 49, true +// gas irOptimized: 113078 +// gas legacy: 120738 +// gas legacyOptimized: 112505 +// fillDestArray() +// gas irOptimized: 200426 +// gas legacy: 218746 +// gas legacyOptimized: 204648 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, true, 6, 7, 8, 9, true, 11, 12, 13, 14, true, 16, 17, 18, 19, true, 21, 22, 23, 24, true, 26, 27, 28, 29, true, 31, 32, 33, 34, true, 36, 37, 38, 39, true, 41, 42, 43, 44, true, 46, 47, 48, 49, true +// gas irOptimized: 113169 +// gas legacy: 120742 +// gas legacyOptimized: 112518 +// destArray() -> 51, 52, 53, 54, true, 56, 57, 58, 59, true, 61, 62, 63, 64, true, 66, 67, 68, 69, true, 71, 72, 73, 74, true, 76, 77, 78, 79, true, 81, 82, 83, 84, true, 86, 87, 88, 89, true, 91, 92, 93, 94, true, 96, 97, 98, 99, true +// gas irOptimized: 113078 +// gas legacy: 120738 +// gas legacyOptimized: 112505 +// copyToBoundary() +// gas irOptimized: 282623 +// gas legacy: 311362 +// gas legacyOptimized: 282712 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 51, 52, 53, 54, true, 56, 57, 58, 59, true, 61, 62, 63, 64, true, 66, 67, 68, 69, true, 71, 72, 73, 74, true, 76, 77, 78, 79, true, 81, 82, 83, 84, true, 86, 87, 88, 89, true, 91, 92, 93, 94, true, 96, 97, 98, 99, true +// gas irOptimized: 113169 +// gas legacy: 120742 +// gas legacyOptimized: 112518 +// destArray() -> 51, 52, 53, 54, true, 56, 57, 58, 59, true, 61, 62, 63, 64, true, 66, 67, 68, 69, true, 71, 72, 73, 74, true, 76, 77, 78, 79, true, 81, 82, 83, 84, true, 86, 87, 88, 89, true, 91, 92, 93, 94, true, 96, 97, 98, 99, true +// gas irOptimized: 113078 +// gas legacy: 120738 +// gas legacyOptimized: 112505 +// deleteBoundaryArray() +// gas irOptimized: 177968 +// gas legacy: 180997 +// gas legacyOptimized: 178175 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// gas irOptimized: 113169 +// gas legacy: 120742 +// gas legacyOptimized: 112518 +// destArray() -> 51, 52, 53, 54, true, 56, 57, 58, 59, true, 61, 62, 63, 64, true, 66, 67, 68, 69, true, 71, 72, 73, 74, true, 76, 77, 78, 79, true, 81, 82, 83, 84, true, 86, 87, 88, 89, true, 91, 92, 93, 94, true, 96, 97, 98, 99, true +// gas irOptimized: 113078 +// gas legacy: 120738 +// gas legacyOptimized: 112505 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_multislot.sol b/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_multislot.sol new file mode 100644 index 000000000000..55e36cd08e06 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_multislot.sol @@ -0,0 +1,128 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256 a; + uint256 b; + uint256 c; + // 3 slots per struct + } + + struct Canary { + uint256 value; + } + + function getBoundaryArray() internal pure returns (S[10][1] storage arr) { + // 10 structs, each 3 slots = 30 slots total + assembly { + arr.slot := sub(0, 15) + } + } + + function getDest() internal pure returns (S[10][1] storage arr) { + assembly { + arr.slot := 16 + } + } + + function getCanary() internal pure returns (Canary storage canary) { + assembly { + canary.slot := 15 + } + } + + constructor() { + Canary storage canary = getCanary(); + canary.value = type(uint256).max; + } + + function fillBoundaryArray() public { + S[10][1] storage arr = getBoundaryArray(); + for (uint i = 0; i < 10; i++) { + arr[0][i] = S({ + a: 1 + i * 3, + b: 2 + i * 3, + c: 3 + i * 3 + }); + } + } + + function deleteBoundaryArray() public { + S[10][1] storage arr = getBoundaryArray(); + delete arr[0]; + } + + function copyFromBoundary() public { + S[10][1] storage source = getBoundaryArray(); + S[10][1] storage dest = getDest(); + dest[0] = source[0]; + } + + function copyToBoundary() public { + S[10][1] storage source = getDest(); + S[10][1] storage dest = getBoundaryArray(); + dest[0] = source[0]; + } + + function fillDestArray() public { + S[10][1] storage dest = getDest(); + for (uint i = 0; i < 10; i++) { + dest[0][i] = S({ + a: 31 + i * 3, + b: 32 + i * 3, + c: 33 + i * 3 + }); + } + } + + function boundaryArray() public view returns (S[10] memory) { + return getBoundaryArray()[0]; + } + + function destArray() public view returns (S[10] memory) { + return getDest()[0]; + } + + function canaryValue() public view returns (uint256) { + return getCanary().value; + } +} +// ---- +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// destArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// fillBoundaryArray() +// gas irOptimized: 688719 +// gas legacy: 700075 +// gas legacyOptimized: 691605 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 +// destArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// copyFromBoundary() +// gas irOptimized: 748779 +// gas legacy: 767297 +// gas legacyOptimized: 748756 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 +// destArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 +// fillDestArray() +// gas irOptimized: 175623 +// gas legacy: 187093 +// gas legacyOptimized: 178625 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 +// destArray() -> 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 +// copyToBoundary() +// gas irOptimized: 235823 +// gas legacy: 254252 +// gas legacyOptimized: 235722 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 +// destArray() -> 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 +// deleteBoundaryArray() +// gas irOptimized: 137824 +// gas legacy: 137973 +// gas legacyOptimized: 137743 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// destArray() -> 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 diff --git a/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_packed.sol b/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_packed.sol new file mode 100644 index 000000000000..5b4085acf8f9 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_boundary_struct_array_packed.sol @@ -0,0 +1,128 @@ +pragma abicoder v2; + +contract C { + struct S { + uint64 a; + uint64 b; + uint64 c; + uint64 d; + // All fit in one slot (4 * 64 = 256 bits) + } + + struct Canary { + uint256 value; + } + + function getBoundaryArray() internal pure returns (S[10][1] storage arr) { + // 10 structs, each 1 slot = 10 slots total + assembly { + arr.slot := sub(0, 5) + } + } + + function getDest() internal pure returns (S[10][1] storage arr) { + assembly { + arr.slot := 6 + } + } + + function getCanary() internal pure returns (Canary storage canary) { + // Array ends at slot 4, canary at slot 5 + assembly { + canary.slot := 5 + } + } + + constructor() { + Canary storage canary = getCanary(); + canary.value = type(uint256).max; + } + + function fillBoundaryArray() public { + S[10][1] storage arr = getBoundaryArray(); + for (uint i = 0; i < 10; i++) { + arr[0][i] = S({ + a: uint64(1 + i * 4), + b: uint64(2 + i * 4), + c: uint64(3 + i * 4), + d: uint64(4 + i * 4) + }); + } + } + + function deleteBoundaryArray() public { + S[10][1] storage arr = getBoundaryArray(); + delete arr[0]; + } + + function copyFromBoundary() public { + S[10][1] storage source = getBoundaryArray(); + S[10][1] storage dest = getDest(); + dest[0] = source[0]; + } + + function copyToBoundary() public { + S[10][1] storage source = getDest(); + S[10][1] storage dest = getBoundaryArray(); + dest[0] = source[0]; + } + + function fillDestArray() public { + S[10][1] storage dest = getDest(); + for (uint i = 0; i < 10; i++) { + dest[0][i] = S({ + a: uint64(41 + i * 4), + b: uint64(42 + i * 4), + c: uint64(43 + i * 4), + d: uint64(44 + i * 4) + }); + } + } + + function boundaryArray() public view returns (S[10] memory) { + return getBoundaryArray()[0]; + } + + function destArray() public view returns (S[10] memory) { + return getDest()[0]; + } + + function canaryValue() public view returns (uint256) { + return getCanary().value; + } +} +// ---- +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// destArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// fillBoundaryArray() +// gas irOptimized: 248990 +// gas legacy: 272856 +// gas legacyOptimized: 253856 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 +// destArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// copyFromBoundary() +// gas irOptimized: 274279 +// gas legacy: 298927 +// gas legacyOptimized: 272256 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 +// destArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 +// fillDestArray() +// gas legacy: 101874 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 +// destArray() -> 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 +// gas legacy: 59729 +// copyToBoundary() +// gas irOptimized: 103323 +// gas legacy: 127882 +// gas legacyOptimized: 101222 +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 +// destArray() -> 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 +// deleteBoundaryArray() +// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// boundaryArray() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// destArray() -> 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 diff --git a/test/libsolidity/semanticTests/storage/storage_packed_array_copy.sol b/test/libsolidity/semanticTests/storage/storage_packed_array_copy.sol new file mode 100644 index 000000000000..d4edc5aecd53 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/storage_packed_array_copy.sol @@ -0,0 +1,35 @@ +contract C { + bytes8[9] _x; // 4 per slot + bytes17[10] _y; // 1 per slot, no offset counter + + constructor() { + for (uint256 i = 0; i < _x.length; ++i) _x[i] = bytes8(uint64(i)); + _y[8] = _y[9] = bytes8(uint64(2)); + } + + function getXAsUint() public view returns (uint64[9] memory result) { + for (uint i = 0; i < 9; i++) { + result[i] = uint64(_x[i]); + } + } + + function getYAsUint() public view returns (uint64[10] memory result) { + for (uint i = 0; i < 10; i++) { + result[i] = uint64(bytes8(_y[i])); + } + } + + function copy() public { + _y = _x; + } +} + +// ---- +// getXAsUint() -> 0, 1, 2, 3, 4, 5, 6, 7, 8 +// getYAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 +// copy() +// gas irOptimized: 190810 +// gas legacy: 195580 +// gas legacyOptimized: 190906 +// getXAsUint() -> 0, 1, 2, 3, 4, 5, 6, 7, 8 +// getYAsUint() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol index 1737c35bb87c..bcad9609ee07 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol @@ -41,9 +41,9 @@ contract C is A layout at 42 { // arrayALength() -> 3 // arrayCLength() -> 0 // initCFromAInReverse() -> 3, 2, 1 -// gas irOptimized: 121276 -// gas legacy: 121213 -// gas legacyOptimized: 120843 +// gas irOptimized: 121281 +// gas legacy: 121937 +// gas legacyOptimized: 120853 // clearA() -> // arrayC(uint256): 0 -> 3 // arrayALength() -> 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol index e33df29ea604..47c4786c841d 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol @@ -27,7 +27,7 @@ contract C layout at 42 is A { // setup() -> // gas irOptimized: 159082 // gas legacy: 161738 -// gas legacyOptimized: 160222 +// gas legacyOptimized: 160218 // open(uint256): 3 -> 0x20, 5, "Empty" // open(uint256): 2 -> 0x20, 6, "Locked" // open(uint256): 1 -> 0x20, 7, "Monster" diff --git a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol index 037ff20679f0..fccdf0030ffb 100644 --- a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol @@ -37,7 +37,7 @@ contract C { // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121282 -// gas legacy: 122977 -// gas legacyOptimized: 121652 +// gas legacy: 125480 +// gas legacyOptimized: 121695 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol index 600eb35ab2ee..50babde562ce 100644 --- a/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol +++ b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol @@ -88,8 +88,8 @@ contract Test { // ---- // test1() -> true // gas irOptimized: 152965 -// gas legacy: 153010 -// gas legacyOptimized: 152636 +// gas legacy: 155952 +// gas legacyOptimized: 152864 // test2() -> true // test3() -> true // test4() -> true diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol index 7188e1befe7a..9f0b7cbe64c9 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol @@ -45,7 +45,7 @@ contract C { // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121454 -// gas legacy: 123114 -// gas legacyOptimized: 121659 +// gas legacy: 125617 +// gas legacyOptimized: 121699 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol index 54b659ba0757..3e86495713be 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol @@ -53,13 +53,13 @@ contract C { // ---- // from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 122720 -// gas legacy: 130131 -// gas legacyOptimized: 128648 +// gas legacy: 125558 +// gas legacyOptimized: 123322 // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121424 -// gas legacy: 123190 -// gas legacyOptimized: 121758 +// gas legacy: 125693 +// gas legacyOptimized: 121804 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 114852 -// gas legacy: 122423 -// gas legacyOptimized: 120698 +// gas legacy: 117950 +// gas legacyOptimized: 115526 diff --git a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol index d020998b47c5..b31d0e580444 100644 --- a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol @@ -46,16 +46,16 @@ contract C { // ---- // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121515 -// gas legacy: 123051 -// gas legacyOptimized: 121704 +// gas legacy: 125554 +// gas legacyOptimized: 121747 // from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121559 -// gas legacy: 123109 -// gas legacyOptimized: 121756 +// gas legacy: 125612 +// gas legacyOptimized: 121799 // from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 122740 -// gas legacy: 129996 -// gas legacyOptimized: 128644 +// gas legacy: 125423 +// gas legacyOptimized: 123323 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 114824 // gas legacy: 118207 diff --git a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol index e50265e5175d..3912a4655505 100644 --- a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol +++ b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol @@ -25,7 +25,7 @@ contract c { // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true // gas irOptimized: 133557 // gas legacy: 134624 -// gas legacyOptimized: 133856 +// gas legacyOptimized: 133857 // test(uint256): 32 -> "3" // storageEmpty -> 0 // copy() -> true @@ -33,7 +33,7 @@ contract c { // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true // gas irOptimized: 133557 // gas legacy: 134624 -// gas legacyOptimized: 133856 +// gas legacyOptimized: 133857 // storageEmpty -> 0 // del() -> true // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol index a8e29dcad8ee..12cbf0799e04 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol @@ -33,4 +33,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0, 0, 0 -// gas irOptimized: 93830 +// gas irOptimized: 93835 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol index cea1105669aa..cd49ea27ad0e 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol @@ -42,10 +42,10 @@ contract C { } // ---- // f() -> -// gas irOptimized: 113465 -// gas legacy: 113591 -// gas legacyOptimized: 113098 +// gas irOptimized: 113388 +// gas legacy: 113588 +// gas legacyOptimized: 113104 // g() -> -// gas irOptimized: 118828 -// gas legacy: 118764 -// gas legacyOptimized: 118168 +// gas irOptimized: 118768 +// gas legacy: 118766 +// gas legacyOptimized: 118188 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol index 871c614f5621..1a047049f205 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol @@ -27,4 +27,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0 -// gas irOptimized: 89435 +// gas irOptimized: 89468 diff --git a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol index 26e8294e3ac9..47fa27fe3c28 100644 --- a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol +++ b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol @@ -30,5 +30,5 @@ contract C { // ---- // f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4 // gas irOptimized: 197102 -// gas legacy: 199887 -// gas legacyOptimized: 196845 +// gas legacy: 205706 +// gas legacyOptimized: 196739 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol index 015d51c1f54b..03c6e11bcc3c 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol @@ -49,13 +49,13 @@ contract C { } // ---- // test_f() -> true -// gas irOptimized: 122201 -// gas legacy: 125333 -// gas legacyOptimized: 122693 +// gas irOptimized: 122114 +// gas legacy: 126162 +// gas legacyOptimized: 122757 // test_g() -> true -// gas irOptimized: 106408 -// gas legacy: 111133 -// gas legacyOptimized: 106925 +// gas irOptimized: 106248 +// gas legacy: 111824 +// gas legacyOptimized: 106606 // addresses(uint256): 0 -> 0x18 // addresses(uint256): 1 -> 0x19 // addresses(uint256): 3 -> 0x1b diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol index 292b9fbfe352..0815a2da7ace 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol @@ -25,17 +25,17 @@ contract C { // f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> // gas irOptimized: 44237 // gas legacy: 47154 -// gas legacyOptimized: 45018 +// gas legacyOptimized: 44982 // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 // gas irOptimized: 68578 -// gas legacy: 75429 -// gas legacyOptimized: 74244 +// gas legacy: 71400 +// gas legacyOptimized: 69139 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" // gas irOptimized: 68635 -// gas legacy: 75125 -// gas legacyOptimized: 74331 +// gas legacy: 71231 +// gas legacyOptimized: 69289 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 // l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol index 585249f2f539..6e07e74e9f71 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol @@ -29,13 +29,13 @@ contract C { // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 // gas irOptimized: 68898 -// gas legacy: 76511 -// gas legacyOptimized: 74832 +// gas legacy: 72336 +// gas legacyOptimized: 69607 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" // gas irOptimized: 68937 -// gas legacy: 76198 -// gas legacyOptimized: 74919 +// gas legacy: 72167 +// gas legacyOptimized: 69802 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 // l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 4d810f970987..eda17b3c2775 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -16,11 +16,11 @@ contract C { // bytecodeFormat: legacy // ---- // constructor() -> -// gas irOptimized: 70760 +// gas irOptimized: 70924 // gas irOptimized code: 94600 -// gas legacy: 82428 +// gas legacy: 82688 // gas legacy code: 153800 -// gas legacyOptimized: 69400 +// gas legacyOptimized: 69675 // gas legacyOptimized code: 79200 // initCode() -> 0x20, 0 // f() -> true diff --git a/test/libsolidity/semanticTests/various/create_calldata.sol b/test/libsolidity/semanticTests/various/create_calldata.sol index 7e3e326228a7..c4d17d4299ca 100644 --- a/test/libsolidity/semanticTests/various/create_calldata.sol +++ b/test/libsolidity/semanticTests/various/create_calldata.sol @@ -10,10 +10,10 @@ contract C { // bytecodeFormat: legacy // ---- // constructor(): 42 -> -// gas irOptimized: 68239 +// gas irOptimized: 68387 // gas irOptimized code: 69000 -// gas legacy: 78076 +// gas legacy: 78348 // gas legacy code: 90200 -// gas legacyOptimized: 68321 +// gas legacyOptimized: 68548 // gas legacyOptimized code: 64600 // s() -> 0x20, 0 diff --git a/test/libsolidity/semanticTests/various/destructuring_assignment.sol b/test/libsolidity/semanticTests/various/destructuring_assignment.sol index a961870ee5f2..44fcd0f6aaa2 100644 --- a/test/libsolidity/semanticTests/various/destructuring_assignment.sol +++ b/test/libsolidity/semanticTests/various/destructuring_assignment.sol @@ -33,6 +33,6 @@ contract C { } // ---- // f(bytes): 0x20, 0x5, "abcde" -> 0 -// gas irOptimized: 242027 -// gas legacy: 243281 -// gas legacyOptimized: 242392 +// gas irOptimized: 242037 +// gas legacy: 246685 +// gas legacyOptimized: 242396 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 8430da4e8d12..1af8a04195a4 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -20,5 +20,5 @@ contract C { // ---- // g() -> 2, 6 // gas irOptimized: 178195 -// gas legacy: 180653 -// gas legacyOptimized: 179144 +// gas legacy: 181357 +// gas legacyOptimized: 179055 diff --git a/test/libsolidity/syntaxTests/array/copy_calldata_struct_array_to_storage_legacy.sol b/test/libsolidity/syntaxTests/array/copy_calldata_struct_array_to_storage_legacy.sol new file mode 100644 index 000000000000..8c45b5b9f520 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/copy_calldata_struct_array_to_storage_legacy.sol @@ -0,0 +1,16 @@ +contract C { + struct S { + uint256 a; + uint256 b; + } + + S[] storageArray; + + function copyFromCalldata(S[] calldata calldataArray) public { + storageArray = calldataArray; + } +} +// ==== +// compileViaYul: false +// ---- +// UnimplementedFeatureError 1834: (0-208): Copying of type struct C.S calldata[] calldata to storage is not supported in legacy (only supported by the IR pipeline). Hint: try compiling with `--via-ir` (CLI) or the equivalent `viaIR: true` (Standard JSON). diff --git a/test/libsolidity/syntaxTests/array/copy_memory_struct_array_to_storage_legacy.sol b/test/libsolidity/syntaxTests/array/copy_memory_struct_array_to_storage_legacy.sol new file mode 100644 index 000000000000..86e8bf1f6344 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/copy_memory_struct_array_to_storage_legacy.sol @@ -0,0 +1,17 @@ +contract C { + struct S { + uint256 a; + uint256 b; + } + + S[] storageArray; + + function copyFromMemory() public { + S[] memory memArray = new S[](3); + storageArray = memArray; + } +} +// ==== +// compileViaYul: false +// ---- +// UnimplementedFeatureError 1834: (0-217): Copying of type struct C.S memory[] memory to storage is not supported in legacy (only supported by the IR pipeline). Hint: try compiling with `--via-ir` (CLI) or the equivalent `viaIR: true` (Standard JSON). From 1ebf5395e9ccc46ea239a2cdbd2a83e0a9379753 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:48:39 -0300 Subject: [PATCH 24/33] Update Changelog.md and add bug entry for LostStorageArrayWriteOnSlotOverflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- Changelog.md | 3 + docs/bugs.json | 10 +++ docs/bugs_by_version.json | 142 +++++++++++++++++++++++++++++++++++--- 3 files changed, 146 insertions(+), 9 deletions(-) diff --git a/Changelog.md b/Changelog.md index 7ed3d7ef64d9..27e1cb33a29f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,8 @@ ### 0.8.32 (unreleased) +Important Bugfixes: +* Code Generator: Fix a bug in clearing/copying of arrays that straddle the end of storage, potentially resulting in assignment/initialization/`delete`/`push()`/`pop()` skipping some or all of the intended storage writes. + Language Features: Compiler Features: diff --git a/docs/bugs.json b/docs/bugs.json index 800524669048..0c0b0493d735 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,14 @@ [ + { + "uid": "SOL-2025-1", + "name": "LostStorageArrayWriteOnSlotOverflow", + "summary": "Operations that involve clearing or copying from arrays that straddle the end of storage could result in silent data retention.", + "description": "Solidity makes it possible to define variables that extend past the last (2**256-th) slot of storage, which results in wrap-around back to slot zero. Since EVM uses 256-bit integer arithmetic, most operations on such variables just work. The only situation which requires special attention is iteration against absolute slot addresses: the invariant that the last slot belonging to a variable has the highest address does not hold. When implemented incorrectly, a loop over an array will immediately terminate if the container spans the end of storage - due to the initial position already being greater than the end position. This affected storage array clearing loops generated by both evmasm and IR pipelines. Additionally, (only in the evmasm pipeline) copying operations whose source was an array straddling the end of storage were also affected. At the language level, the buggy code would be generated for array assignment, array initialization, delete operator, .pop() and .push(). Note that a clearing loop is inserted by the compiler not only for invocations of the delete operator, but also to zero storage when overwriting a longer array with a shorter one, popping an element or even pushing an empty element to a dynamic array. Since clearing is a separate loop, it is possible for the bug to only affect it and not the copy operation it follows (which is always the case in the IR pipeline). The bug is extremely unlikely to be triggered accidentally due to the probabilistic impossibility of a short dynamic array being allocated right at the storage boundary. On the other hand, scenarios in which a user may place a static array there intentionally do not seem realistic and are limited to unusual layouts, in which a contract does not place any storage variables at slot zero (otherwise they would overlap the array).", + "link": "https://blog.soliditylang.org/2025/12/18/lost-storage-array-write-on-slot-overflow-bug/", + "introduced": "0.1.0", + "fixed": "0.8.32", + "severity": "low" + }, { "uid": "SOL-2023-3", "name": "VerbatimInvalidDeduplication", diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 881f5eabee99..94e814892df9 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1,6 +1,7 @@ { "0.1.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -23,6 +24,7 @@ }, "0.1.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -45,6 +47,7 @@ }, "0.1.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -67,6 +70,7 @@ }, "0.1.3": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -89,6 +93,7 @@ }, "0.1.4": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -112,6 +117,7 @@ }, "0.1.5": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -135,6 +141,7 @@ }, "0.1.6": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -160,6 +167,7 @@ }, "0.1.7": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -185,6 +193,7 @@ }, "0.2.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -211,6 +220,7 @@ }, "0.2.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -237,6 +247,7 @@ }, "0.2.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -263,6 +274,7 @@ }, "0.3.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -291,6 +303,7 @@ }, "0.3.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -318,6 +331,7 @@ }, "0.3.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -345,6 +359,7 @@ }, "0.3.3": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -371,6 +386,7 @@ }, "0.3.4": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -397,6 +413,7 @@ }, "0.3.5": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -423,6 +440,7 @@ }, "0.3.6": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -447,6 +465,7 @@ }, "0.4.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -471,6 +490,7 @@ }, "0.4.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -495,6 +515,7 @@ }, "0.4.10": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -518,6 +539,7 @@ }, "0.4.11": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -540,6 +562,7 @@ }, "0.4.12": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -561,6 +584,7 @@ }, "0.4.13": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -582,6 +606,7 @@ }, "0.4.14": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -602,6 +627,7 @@ }, "0.4.15": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -621,6 +647,7 @@ }, "0.4.16": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -643,6 +670,7 @@ }, "0.4.17": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -666,6 +694,7 @@ }, "0.4.18": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -688,6 +717,7 @@ }, "0.4.19": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -711,6 +741,7 @@ }, "0.4.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -734,6 +765,7 @@ }, "0.4.20": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -757,6 +789,7 @@ }, "0.4.21": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -780,6 +813,7 @@ }, "0.4.22": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -803,6 +837,7 @@ }, "0.4.23": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -825,6 +860,7 @@ }, "0.4.24": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -847,6 +883,7 @@ }, "0.4.25": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -867,6 +904,7 @@ }, "0.4.26": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -884,6 +922,7 @@ }, "0.4.3": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -906,6 +945,7 @@ }, "0.4.4": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -927,6 +967,7 @@ }, "0.4.5": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -951,6 +992,7 @@ }, "0.4.6": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -974,6 +1016,7 @@ }, "0.4.7": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -997,6 +1040,7 @@ }, "0.4.8": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -1020,6 +1064,7 @@ }, "0.4.9": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "KeccakCaching", "EmptyByteArrayCopy", @@ -1043,6 +1088,7 @@ }, "0.5.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1063,6 +1109,7 @@ }, "0.5.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1083,6 +1130,7 @@ }, "0.5.10": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1101,6 +1149,7 @@ }, "0.5.11": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1118,6 +1167,7 @@ }, "0.5.12": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1135,6 +1185,7 @@ }, "0.5.13": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1152,6 +1203,7 @@ }, "0.5.14": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1171,6 +1223,7 @@ }, "0.5.15": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1189,6 +1242,7 @@ }, "0.5.16": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1206,6 +1260,7 @@ }, "0.5.17": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1222,6 +1277,7 @@ }, "0.5.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1242,6 +1298,7 @@ }, "0.5.3": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1262,6 +1319,7 @@ }, "0.5.4": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1282,6 +1340,7 @@ }, "0.5.5": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1304,6 +1363,7 @@ }, "0.5.6": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1326,6 +1386,7 @@ }, "0.5.7": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "DirtyBytesArrayToStorage", "ABIDecodeTwoDimensionalArrayMemory", "KeccakCaching", @@ -1346,6 +1407,7 @@ }, "0.5.8": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1367,6 +1429,7 @@ }, "0.5.9": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1387,6 +1450,7 @@ }, "0.6.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1405,6 +1469,7 @@ }, "0.6.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", "NestedCalldataArrayAbiReencodingSizeValidation", @@ -1422,6 +1487,7 @@ }, "0.6.10": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1438,6 +1504,7 @@ }, "0.6.11": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1454,6 +1521,7 @@ }, "0.6.12": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1470,6 +1538,7 @@ }, "0.6.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", @@ -1488,6 +1557,7 @@ }, "0.6.3": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", @@ -1506,6 +1576,7 @@ }, "0.6.4": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", @@ -1524,6 +1595,7 @@ }, "0.6.5": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", @@ -1542,6 +1614,7 @@ }, "0.6.6": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", "DirtyBytesArrayToStorage", @@ -1559,6 +1632,7 @@ }, "0.6.7": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1577,6 +1651,7 @@ }, "0.6.8": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1592,6 +1667,7 @@ }, "0.6.9": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1609,6 +1685,7 @@ }, "0.7.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1625,6 +1702,7 @@ }, "0.7.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1642,6 +1720,7 @@ }, "0.7.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1658,6 +1737,7 @@ }, "0.7.3": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1673,6 +1753,7 @@ }, "0.7.4": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1687,6 +1768,7 @@ }, "0.7.5": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1701,6 +1783,7 @@ }, "0.7.6": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1715,6 +1798,7 @@ }, "0.8.0": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1729,6 +1813,7 @@ }, "0.8.1": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1743,6 +1828,7 @@ }, "0.8.10": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1755,6 +1841,7 @@ }, "0.8.11": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1768,6 +1855,7 @@ }, "0.8.12": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1781,6 +1869,7 @@ }, "0.8.13": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1795,6 +1884,7 @@ }, "0.8.14": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1807,6 +1897,7 @@ }, "0.8.15": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1817,6 +1908,7 @@ }, "0.8.16": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1826,6 +1918,7 @@ }, "0.8.17": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1834,6 +1927,7 @@ }, "0.8.18": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1842,6 +1936,7 @@ }, "0.8.19": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1850,6 +1945,7 @@ }, "0.8.2": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1864,6 +1960,7 @@ }, "0.8.20": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1872,46 +1969,63 @@ }, "0.8.21": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication" ], "released": "2023-07-19" }, "0.8.22": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication" ], "released": "2023-10-25" }, "0.8.23": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2023-11-08" }, "0.8.24": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-01-25" }, "0.8.25": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-03-14" }, "0.8.26": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-05-21" }, "0.8.27": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-09-04" }, "0.8.28": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-10-09" }, "0.8.29": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2025-03-12" }, "0.8.3": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1924,15 +2038,20 @@ "released": "2021-03-23" }, "0.8.30": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2025-05-07" }, "0.8.31": { - "bugs": [], + "bugs": [ + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2025-12-03" }, "0.8.4": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1945,6 +2064,7 @@ }, "0.8.5": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1958,6 +2078,7 @@ }, "0.8.6": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1971,6 +2092,7 @@ }, "0.8.7": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1984,6 +2106,7 @@ }, "0.8.8": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1998,6 +2121,7 @@ }, "0.8.9": { "bugs": [ + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", From b34a0545eef0e9424e4e5bf6d6bf07c65a94dbc6 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 17 Dec 2025 13:13:33 +0100 Subject: [PATCH 25/33] Fix `string|bytes.concat` assignment to a constant variable. --- libsolidity/analysis/TypeChecker.cpp | 17 +++++++++++++++++ libsolidity/ast/Types.cpp | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f5c093dbd411..8556487ff4ca 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3271,11 +3271,28 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) // TODO some members might be pure, but for example `address(0x123).balance` is not pure // although every subexpression is, so leaving this limited for now. if (auto tt = dynamic_cast(exprType)) + { if ( tt->actualType()->category() == Type::Category::Enum || tt->actualType()->category() == Type::Category::UserDefinedValueType ) annotation.isPure = true; + + // `concat` purity depends also on its arguments, but this is checked later, in visit(FunctionCall...) + // This covers `bytes.concat` and `string.concat`. + if (tt->actualType()->category() == Type::Category::Array) + { + if ( + auto const* funcType = dynamic_cast(annotation.type); + funcType && + ( + funcType->kind() == FunctionType::Kind::StringConcat || + funcType->kind() == FunctionType::Kind::BytesConcat + ) + ) + annotation.isPure = true; + } + } if ( auto const* functionType = dynamic_cast(exprType); functionType && diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index f5c83b0cf991..316d99ba3edc 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3713,7 +3713,9 @@ bool FunctionType::isPure() const m_kind == Kind::ABIDecode || m_kind == Kind::MetaType || m_kind == Kind::Wrap || - m_kind == Kind::Unwrap; + m_kind == Kind::Unwrap || + m_kind == Kind::BytesConcat || + m_kind == Kind::StringConcat; } TypePointers FunctionType::parseElementaryTypeVector(strings const& _types) From f4b7f98893f570365319673ba64339b61e5e7497 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 17 Dec 2025 13:14:08 +0100 Subject: [PATCH 26/33] Add syntax tests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- .../initialization/abi_decode_const_args.sol | 7 ++ .../abi_decode_non_const_args.sol | 9 +++ .../abi_encode_call_const_args.sol | 5 ++ .../abi_encode_call_non_const_args.sol | 11 +++ .../abi_encoding_builtin_const_args.sol} | 0 .../abi_encoding_builtin_non_const_args.sol | 13 +++ .../addmod_by_zero.sol} | 0 .../addmod_mulmod_rational_arg.sol} | 0 .../initialization/block_tx_msg_property.sol | 80 +++++++++++++++++++ .../bytes_concat_const_args.sol | 11 +++ .../bytes_concat_non_const_args.sol | 17 ++++ .../constant_with_cyclic_dependency_1.sol} | 0 .../constant_with_cyclic_dependency_2.sol} | 0 .../constant_with_cyclic_dependency_3.sol} | 0 .../constant_with_cyclic_dependency_4.sol} | 0 .../constant_with_cyclic_dependency_5.sol} | 0 .../constant_with_cyclic_dependency_file.sol} | 0 ...th_cyclic_dependency_file_and_library.sol} | 0 ...nstant_with_cyclic_dependency_library.sol} | 0 .../{ => initialization}/division_by_zero.sol | 0 .../function_pointer_call.sol} | 0 .../math_builtin_opcode_based_const_args.sol | 14 ++++ ...th_builtin_opcode_based_non_const_args.sol | 12 +++ ...th_builtin_precompile_based_const_args.sol | 16 ++++ ...uiltin_precompile_based_non_const_args.sol | 10 +++ .../modulo_by_zero.sol} | 0 .../mulmod_by_zero.sol} | 0 .../string_concat_const_args.sol | 9 +++ .../string_concat_non_const_args.sol | 14 ++++ .../constants/initialization/type_info.sol | 23 ++++++ 30 files changed, 251 insertions(+) create mode 100644 test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol rename test/libsolidity/syntaxTests/constants/{abi_encoding_constant.sol => initialization/abi_encoding_builtin_const_args.sol} (100%) create mode 100644 test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol rename test/libsolidity/syntaxTests/constants/{addmod_zero.sol => initialization/addmod_by_zero.sol} (100%) rename test/libsolidity/syntaxTests/constants/{addmod_mulmod_rational.sol => initialization/addmod_mulmod_rational_arg.sol} (100%) create mode 100644 test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_1.sol => initialization/constant_with_cyclic_dependency_1.sol} (100%) rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_2.sol => initialization/constant_with_cyclic_dependency_2.sol} (100%) rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_3.sol => initialization/constant_with_cyclic_dependency_3.sol} (100%) rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_4.sol => initialization/constant_with_cyclic_dependency_4.sol} (100%) rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_5.sol => initialization/constant_with_cyclic_dependency_5.sol} (100%) rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_file_constants.sol => initialization/constant_with_cyclic_dependency_file.sol} (100%) rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_file_and_library_constants.sol => initialization/constant_with_cyclic_dependency_file_and_library.sol} (100%) rename test/libsolidity/syntaxTests/constants/{cyclic_dependency_library_constants.sol => initialization/constant_with_cyclic_dependency_library.sol} (100%) rename test/libsolidity/syntaxTests/constants/{ => initialization}/division_by_zero.sol (100%) rename test/libsolidity/syntaxTests/constants/{assign_constant_function_value.sol => initialization/function_pointer_call.sol} (100%) create mode 100644 test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol rename test/libsolidity/syntaxTests/constants/{mod_zero.sol => initialization/modulo_by_zero.sol} (100%) rename test/libsolidity/syntaxTests/constants/{mulmod_zero.sol => initialization/mulmod_by_zero.sol} (100%) create mode 100644 test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol create mode 100644 test/libsolidity/syntaxTests/constants/initialization/type_info.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol new file mode 100644 index 000000000000..6f597ae73a6e --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol @@ -0,0 +1,7 @@ +bytes constant aEncoded = abi.encode( + hex"aaaa" +); + +contract A { + bytes constant a = abi.decode(aEncoded, (bytes)); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol new file mode 100644 index 000000000000..e5772333a005 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol @@ -0,0 +1,9 @@ +contract A { + function encoded() private view returns (bytes memory) { + return abi.encode(hex"aaaa"); + } + + bytes constant a = abi.decode(encoded(), (bytes)); +} +// ---- +// TypeError 8349: (142-172): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol new file mode 100644 index 000000000000..e716694cc311 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol @@ -0,0 +1,5 @@ +contract A { + bool constant FLAG = true; + function f(uint, bool) external {} + bytes constant fCallA = abi.encodeCall(A.f, (123, FLAG)); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol new file mode 100644 index 000000000000..b49213742efe --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol @@ -0,0 +1,11 @@ +contract A { + function f(uint a) external {} + + function getA() private view returns(uint) { + return 1; + } + + bytes constant fCallA = abi.encodeCall(A.f, (getA())); +} +// ---- +// TypeError 8349: (151-180): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_const_args.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol rename to test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_const_args.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol new file mode 100644 index 000000000000..7e399a0d00d4 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol @@ -0,0 +1,13 @@ +contract C { + uint k = 1; + + bytes32 constant a = keccak256(abi.encode(1, k)); + bytes32 constant b = keccak256(abi.encodePacked(uint(1), k)); + bytes32 constant c = keccak256(abi.encodeWithSelector(0x12345678, k, 2)); + bytes32 constant d = keccak256(abi.encodeWithSignature("f()", 1, k)); +} +// ---- +// TypeError 8349: (55-82): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (109-148): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (175-226): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (253-300): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/addmod_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/addmod_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/addmod_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/addmod_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol b/test/libsolidity/syntaxTests/constants/initialization/addmod_mulmod_rational_arg.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol rename to test/libsolidity/syntaxTests/constants/initialization/addmod_mulmod_rational_arg.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol b/test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol new file mode 100644 index 000000000000..54381a2573a1 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol @@ -0,0 +1,80 @@ +bytes32 constant blockhGlobal = blockhash(1); +bytes32 constant blobhGlobal = blobhash(1); +uint constant bfGlobal = block.basefee; +uint constant blobbfGlobal = block.blobbasefee; +uint constant chainIdGlobal = block.chainid; +address constant coinbaseGlobal = block.coinbase; +uint constant diffGlobal = block.difficulty; +uint constant gaslimitGlobal = block.gaslimit; +uint constant numberGlobal = block.number; +uint constant prevrandaoGlobal = block.prevrandao; +uint constant timestampGlobal = block.timestamp; +uint constant gGlobal = gasleft(); +bytes constant dataGlobal = msg.data; +address constant senderGlobal = msg.sender; +bytes4 constant sigGlobal = msg.sig; +uint constant valueGlobal = msg.value; +uint constant gaspriceGlobal = tx.gasprice; +address constant originGlobal = tx.origin; + +contract A { + bytes32 constant blockh = blockhash(1); + bytes32 constant blobh = blobhash(1); + uint constant bf = block.basefee; + uint constant blobbf = block.blobbasefee; + uint constant chainId = block.chainid; + address constant coinbase = block.coinbase; + uint constant diff = block.difficulty; + uint constant gaslimit = block.gaslimit; + uint constant number = block.number; + uint constant prevrandao = block.prevrandao; + uint constant timestamp = block.timestamp; + uint constant g = gasleft(); + bytes constant data = msg.data; + address constant sender = msg.sender; + bytes4 constant sig = msg.sig; + uint constant value = msg.value; + uint constant gasprice = tx.gasprice; + address constant origin = tx.origin; +} +// ==== +// EVMVersion: >=cancun +// ---- +// TypeError 8349: (32-44): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (77-88): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (115-128): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (159-176): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (208-221): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (257-271): Initial value for constant variable has to be compile-time constant. +// Warning 8417: (300-316): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// TypeError 8349: (300-316): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (349-363): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (394-406): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (441-457): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (491-506): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (532-541): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (571-579): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (613-623): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (653-660): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (690-699): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (732-743): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (777-786): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (832-844): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (875-886): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (911-924): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (953-970): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1000-1013): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1047-1061): Initial value for constant variable has to be compile-time constant. +// Warning 8417: (1088-1104): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// TypeError 8349: (1088-1104): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1135-1149): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1178-1190): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1223-1239): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1271-1286): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1310-1319): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1347-1355): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1387-1397): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1425-1432): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1460-1469): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1500-1511): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1543-1552): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol new file mode 100644 index 000000000000..2d87ba56c48f --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol @@ -0,0 +1,11 @@ +bytes constant aaaa = hex"aaaa"; + +bytes constant abcGlobal = bytes.concat(aaaa, hex"bbbb", hex"cccc"); + +contract A { + bytes public constant abc = bytes.concat(aaaa, hex"bbbb", hex"cccc"); + + bytes public constant abcCopy = abc; + bytes public constant abcGlobalCopy = abcGlobal; + bytes public constant abcabc = bytes.concat(abc, abcGlobal); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol new file mode 100644 index 000000000000..225731c1ffde --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol @@ -0,0 +1,17 @@ +contract A { + function getData() public view returns (bytes memory) { + return msg.data; + } + + function getDataPure() public pure returns (bytes memory) { + return hex"ffff"; + } + + bytes constant abData = bytes.concat(hex"aaaa", hex"bbbb", msg.data); + bytes constant abgetData = bytes.concat(hex"aaaa", hex"bbbb", getData()); + bytes constant abgetDataPure = bytes.concat(hex"aaaa", hex"bbbb", getDataPure()); +} +// ---- +// TypeError 8349: (230-274): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (307-352): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (389-438): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_1.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_1.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_2.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_2.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_3.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_3.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_4.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_4.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_5.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_5.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_file_constants.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_file_constants.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_file_and_library_constants.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file_and_library.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_file_and_library_constants.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file_and_library.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_library_constants.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_library.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_library_constants.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_library.sol diff --git a/test/libsolidity/syntaxTests/constants/division_by_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/division_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/division_by_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/division_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/assign_constant_function_value.sol b/test/libsolidity/syntaxTests/constants/initialization/function_pointer_call.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/assign_constant_function_value.sol rename to test/libsolidity/syntaxTests/constants/initialization/function_pointer_call.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol new file mode 100644 index 000000000000..aa13e02b4d1e --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol @@ -0,0 +1,14 @@ +uint256 constant k = 7; +bytes constant data = hex"ffff"; + +uint256 constant amodGlobal = addmod(1, 8, k); +uint256 constant mmodGlobal = mulmod(1, 8, k); +bytes32 constant keccakGlobal = keccak256(hex"ffff"); +bytes32 constant keccakConstArgGlobal = keccak256(data); + +contract A { + uint256 constant amod = addmod(1, 8, k); + uint256 constant mmod = mulmod(1, 8, k); + bytes32 constant keccak = keccak256(hex"ffff"); + bytes32 constant keccakConstArg = keccak256(data); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol new file mode 100644 index 000000000000..208437ab7045 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol @@ -0,0 +1,12 @@ +contract A { + uint256 k = 7; + uint256 constant amod = addmod(1, 8, k); + uint256 constant mmod = mulmod(1, 8, k); + + bytes data = hex"ffff"; + bytes32 constant keccak = keccak256(data); +} +// ---- +// TypeError 8349: (60-75): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (105-120): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (181-196): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol new file mode 100644 index 000000000000..57626ec2f362 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol @@ -0,0 +1,16 @@ +uint8 constant k = 1; +bytes constant data = hex"ffff"; + +bytes32 constant sGlobal = sha256(hex"ffff"); +bytes32 constant sConstArgGlobal = sha256(data); +address constant addrGlobal = ecrecover("1234", k, "0", abi.decode("", (bytes2))); +bytes20 constant ripemdGlobal = ripemd160(hex"ffff"); +bytes20 constant ripemdConstArgGlobal = ripemd160(data); + +contract A { + bytes32 constant s = sha256(hex"ffff"); + bytes32 constant sConstArg = sha256(data); + address constant addr = ecrecover("1234", k, "0", abi.decode("", (bytes2))); + bytes20 constant ripemd = ripemd160(hex"ffff"); + bytes20 constant ripemdConstArg = ripemd160(data); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol new file mode 100644 index 000000000000..fef5ccc88ca5 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol @@ -0,0 +1,10 @@ +contract A { + bytes data = hex"ffff"; + bytes32 constant sha = sha256(data); + bytes20 constant ripemd = ripemd160(data); + address constant addr = ecrecover("1234", 1, "0", abi.decode(data, (bytes2))); +} +// ---- +// TypeError 8349: (68-80): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (112-127): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (157-210): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/mod_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/modulo_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/mod_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/modulo_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/mulmod_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/mulmod_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/mulmod_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/mulmod_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol new file mode 100644 index 000000000000..bc676d101573 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol @@ -0,0 +1,9 @@ +string constant abcGlobal = string.concat("aaaa", "bbbb", "cccc"); + +contract A { + string public constant abc = string.concat("aaaa", "bbbb","cccc"); + + string public constant abcCopy = abc; + string public constant abcGlobalCopy = abcGlobal; + string public constant abcabc = string.concat(abc, abcGlobal); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol new file mode 100644 index 000000000000..f8b4aa6e29e7 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol @@ -0,0 +1,14 @@ +contract A { + string name = "name"; + + function getName() public view returns (string memory) { + return name; + } + + string public constant abName = string.concat("aaaa", "bbbb", name); + + string public constant abgetName = string.concat("aaaa", "bbbb",getName()); +} +// ---- +// TypeError 8349: (165-200): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (242-281): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/type_info.sol b/test/libsolidity/syntaxTests/constants/initialization/type_info.sol new file mode 100644 index 000000000000..51cfaa3a56e2 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/type_info.sol @@ -0,0 +1,23 @@ +string constant aNameGlobal = type(A).name; +bytes4 constant iNameGlobal = type(I).interfaceId; +uint256 constant minGlobal = type(uint256).min; +uint256 constant maxGlobal = type(uint256).max; +bytes constant creationCodeBGlobal = type(B).creationCode; +bytes constant runtimeCodeBGlobal = type(B).runtimeCode; + +contract B { +} + +interface I { + function hello() external pure; + function world(int) external pure; +} + +contract A { + string constant aName = type(A).name; + bytes4 constant iName = type(I).interfaceId; + uint256 constant min = type(uint256).min; + uint256 constant max = type(uint256).max; + bytes constant creationCodeB = type(B).creationCode; + bytes constant runtimeCodeB = type(B).runtimeCode; +} From a4bd1b760aef7e8deaec6c4303a36cf9fed5ac1c Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 17 Dec 2025 13:14:21 +0100 Subject: [PATCH 27/33] Add semantic test --- .../semanticTests/constants/assign_type_info.sol | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/libsolidity/semanticTests/constants/assign_type_info.sol diff --git a/test/libsolidity/semanticTests/constants/assign_type_info.sol b/test/libsolidity/semanticTests/constants/assign_type_info.sol new file mode 100644 index 000000000000..0fca83d547bc --- /dev/null +++ b/test/libsolidity/semanticTests/constants/assign_type_info.sol @@ -0,0 +1,13 @@ +contract A { +} + +contract B { + bytes constant creationCode = type(A).creationCode; + bytes constant runtimeCode = type(A).runtimeCode; + + function nonEmptyCode() public pure returns (bool) { + return creationCode.length > 0 && runtimeCode.length > 0; + } +} +// ---- +// nonEmptyCode() -> true From ba32d8b5ab93219ff343e7162d619c0e66f011f0 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 17 Dec 2025 13:14:50 +0100 Subject: [PATCH 28/33] Update tests. Change error message. --- .../storageLayoutSpecifier/layout_specified_by_bytes_concat.sol | 2 +- .../storageLayoutSpecifier/layout_specified_by_kecak256.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol index d341a5a764d2..77860af8ec0c 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol @@ -1,3 +1,3 @@ contract C layout at uint64(bytes8(bytes.concat("ABCD", "EFGH"))) {} // ---- -// TypeError 1139: (21-65): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1505: (21-65): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol index 539a59c11c07..0b35d60d891e 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol @@ -1,3 +1,3 @@ contract C layout at uint(keccak256(bytes.concat("ABCD"))) {} // ---- -// TypeError 1139: (21-58): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1505: (21-58): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time. From 91a49db7188cba31dc272726e57d17255ca837e4 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 17 Dec 2025 13:15:12 +0100 Subject: [PATCH 29/33] Update tests. Modify to avoid the no effect warning. --- .../array/concat/bytes_concat_valid_type_literal.sol | 4 ++-- .../concat/bytes_concat_wrong_type_empty_string_literal.sol | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol b/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol index f39e9039638d..ff003ca8a025 100644 --- a/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol +++ b/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol @@ -1,6 +1,6 @@ contract C { - function f() public pure { - bytes.concat( + function f() public pure returns (bytes memory) { + return bytes.concat( hex"00", hex"aabbcc", unicode"abc", diff --git a/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol b/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol index afba249f8d4a..a58cf9f3dd92 100644 --- a/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol +++ b/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol @@ -1,6 +1,6 @@ contract C { - function f() public pure { - bytes.concat(hex"", unicode"", ""); + function f() public pure returns (bytes memory) { + return bytes.concat(hex"", unicode"", ""); } } // ---- From 2c0acc50c4fac51e6d2ee3ea876061b7721ac663 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 17 Dec 2025 13:15:25 +0100 Subject: [PATCH 30/33] Update changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 27e1cb33a29f..26f28d21d978 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: Bugfixes: * Codegen: Fix internal compiler error when emitting events via module member access. * TypeChecker: Fix error and event selectors not being considered compile-time constant. +* TypeChecker: Fix `string.concat` and `bytes.concat` with constant arguments not being considered compile-time constant. ### 0.8.31 (2025-12-03) From eb6a45904a3e7e3c7e35eff7cc5d813658848034 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 17 Dec 2025 14:19:37 +0100 Subject: [PATCH 31/33] Add sanity check in the end of `TypeChecker::visit(MemberAccess const& _memberAccess)` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- libsolidity/analysis/TypeChecker.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 8556487ff4ca..ab8f00a3082b 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3409,6 +3409,16 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) if (!annotation.isPure.set()) annotation.isPure = false; + if ( + auto const* funcType = dynamic_cast(annotation.type); + funcType && + funcType->kind() != FunctionType::Kind::Declaration && + funcType->kind() != FunctionType::Kind::Internal && + funcType->kind() != FunctionType::Kind::Error && + funcType->kind() != FunctionType::Kind::Event + ) + solAssert(funcType->isPure() == *annotation.isPure); + return false; } From b28145c60e490a7504ca1c2e4edac16f5ec2e5e7 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Thu, 11 Dec 2025 10:10:47 -0300 Subject: [PATCH 32/33] Update docs about solc-bin.ethereum.org deprecation in favor of binaries.soliditylang.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- docs/installing-solidity.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 01a2f382045b..97a754eaaab0 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -270,10 +270,11 @@ This means that: if you want to be sure whether you are downloading a wasm or an asm.js binary. - Use ``list.json`` instead of ``list.js`` and ``list.txt``. The JSON list format contains all the information from the old ones and more. - - Use https://binaries.soliditylang.org instead of https://solc-bin.ethereum.org. To keep things - simple we moved almost everything related to the compiler under the new ``soliditylang.org`` - domain and this applies to ``solc-bin`` too. While the new domain is recommended, the old one - is still fully supported and guaranteed to point at the same location. + +.. warning:: + - The solc-bin.ethereum.org domain is no longer supported. Going forward, + we recommend any tools which are still using it as the source of Solidity binaries + to switch to binaries.soliditylang.org. .. warning:: From 1c61064d0851acc5dc565e6bac10bf327ed79a2d Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 18 Dec 2025 06:02:37 +0100 Subject: [PATCH 33/33] Fix changelog for 0.8.32 --- Changelog.md | 5 +---- docs/bugs_by_version.json | 4 ++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 26f28d21d978..ad0916815d64 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,11 +1,8 @@ -### 0.8.32 (unreleased) +### 0.8.32 (2025-12-18) Important Bugfixes: * Code Generator: Fix a bug in clearing/copying of arrays that straddle the end of storage, potentially resulting in assignment/initialization/`delete`/`push()`/`pop()` skipping some or all of the intended storage writes. -Language Features: - -Compiler Features: Bugfixes: * Codegen: Fix internal compiler error when emitting events via module member access. diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 94e814892df9..2ecc3c235606 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -2049,6 +2049,10 @@ ], "released": "2025-12-03" }, + "0.8.32": { + "bugs": [], + "released": "2025-12-18" + }, "0.8.4": { "bugs": [ "LostStorageArrayWriteOnSlotOverflow",