From 6738ce6f3379bbf1c2d5b2fff768d21913aa4d97 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:49:55 +0100 Subject: [PATCH 001/121] bump fmtlib to 11.1.4 --- deps/fmtlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/fmtlib b/deps/fmtlib index 0c9fce2ffefe..123913715afe 160000 --- a/deps/fmtlib +++ b/deps/fmtlib @@ -1 +1 @@ -Subproject commit 0c9fce2ffefecfdce794e1859584e25877b7b592 +Subproject commit 123913715afeb8a437e6388b4473fcc4753e1c9a From 363f1ae1dedbf47528dd1d76065032e1ed367b2b Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 11 Mar 2025 13:09:38 -0300 Subject: [PATCH 002/121] Set next version 0.8.30 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d95b7213ebe6..5b39878f26d3 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.29") +set(PROJECT_VERSION "0.8.30") # 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 b1ddcacf6c94..47334fd3dacd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.30 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.29 (2025-03-12) Language Features: From c84cac865295b87caa273b3ed8aaa31b0b121d99 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:44:14 +0100 Subject: [PATCH 003/121] release checklist: mention buildx as requirement for docker_deploy_manual --- ReleaseChecklist.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index f55384230aa4..301cf963e81f 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -6,6 +6,7 @@ - [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc). - [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work). + - [ ] Ubuntu/Debian dependencies of the Docker script: ``docker-buildx``. - [ ] Ubuntu/Debian dependencies of the PPA scripts: ``devscripts``, ``debhelper``, ``dput``, ``git``, ``wget``, ``ca-certificates``. - [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc). - [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang). @@ -79,6 +80,7 @@ At least a day before the release: - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in the [``solidity`` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/s/solidity.rb). ### Docker + - [ ] Make sure ``docker-buildx`` is installed. - [ ] Run ``./scripts/docker_deploy_manual.sh v$VERSION``. ### PPA From 40a4d5d420006168e6c73a1a27a9159cb0b515f0 Mon Sep 17 00:00:00 2001 From: Ocenka Date: Fri, 14 Mar 2025 12:28:24 +0000 Subject: [PATCH 004/121] Minor spelling fix in external test runners base.py --- scripts/externalTests/runners/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/externalTests/runners/base.py b/scripts/externalTests/runners/base.py index cd94fab6b80b..4778206150e2 100644 --- a/scripts/externalTests/runners/base.py +++ b/scripts/externalTests/runners/base.py @@ -74,7 +74,7 @@ def __init__(self, argv, config: TestConfig): def setup_solc(self) -> str: if self.solc_binary_type == "solcjs": - # TODO: add support to solc-js + # TODO: add support for solc-js raise NotImplementedError() print("Setting up solc...") solc_version_output = subprocess.check_output( From d547bf2b67668bc1fd85cf4c6713c50cf5db5b80 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 14 Mar 2025 08:50:53 +0100 Subject: [PATCH 005/121] Release checklist: Updates style - double backticks -> single backticks - remove single space before bullet points --- ReleaseChecklist.md | 200 ++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 301cf963e81f..f5e4ec7cae21 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -1,127 +1,127 @@ ## Checklist for making a release: ### Requirements - - [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js), - [solc-bin](https://github.com/ethereum/solc-bin), [solidity-website](https://github.com/ethereum/solidity-website). - - [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc). - - [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and - a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work). - - [ ] Ubuntu/Debian dependencies of the Docker script: ``docker-buildx``. - - [ ] Ubuntu/Debian dependencies of the PPA scripts: ``devscripts``, ``debhelper``, ``dput``, ``git``, ``wget``, ``ca-certificates``. - - [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc). - - [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang). - - [ ] [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (``/r/ethereum`` requirements). +- [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js), + [solc-bin](https://github.com/ethereum/solc-bin), [solidity-website](https://github.com/ethereum/solidity-website). +- [ ] DockerHub account with push rights to the [`solc` image](https://hub.docker.com/r/ethereum/solc). +- [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and + a gnupg key for your email in the `ethereum.org` domain (has to be version 1, gpg2 won't work). +- [ ] Ubuntu/Debian dependencies of the Docker script: `docker-buildx`. +- [ ] Ubuntu/Debian dependencies of the PPA scripts: `devscripts`, `debhelper`, `dput`, `git`, `wget`, `ca-certificates`. +- [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [`solc` package](https://www.npmjs.com/package/solc). +- [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang). +- [ ] [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (`/r/ethereum` requirements). ### Pre-flight checks At least a day before the release: - - [ ] Run ``make linkcheck`` from within ``docs/`` and fix any broken links it finds. - Ignore false positives caused by ``href`` anchors and dummy links not meant to work. - **Note**: In order to run the link check, make sure you've built the docs first via ``docs.sh``. - - [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded. - - [ ] Make sure that all merged PRs that should have changelog entries do have them. - - [ ] Rerun CI on the top commits of main branches in all repositories that do not have daily activity by creating a test branch or PR: - - [ ] ``solc-js`` - - [ ] ``solc-bin`` (make sure the bytecode comparison check did run) - - [ ] (Optional) Create a prerelease in our Ubuntu PPA by following the steps in the PPA section below on ``develop`` rather than on a tag. - This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle. - - [ ] Verify that the release tarball of ``solc-js`` works. - Bump version locally, add ``soljson.js`` from CI, build it, compare the file structure with the previous version, install it locally and try to use it. - - [ ] Review [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes) to make sure you don't repeat the same mistakes. +- [ ] Run `make linkcheck` from within `docs/` and fix any broken links it finds. + Ignore false positives caused by `href` anchors and dummy links not meant to work. + **Note**: In order to run the link check, make sure you've built the docs first via `docs.sh`. +- [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded. +- [ ] Make sure that all merged PRs that should have changelog entries do have them. +- [ ] Rerun CI on the top commits of main branches in all repositories that do not have daily activity by creating a test branch or PR: + - [ ] `solc-js` + - [ ] `solc-bin` (make sure the bytecode comparison check did run) +- [ ] (Optional) Create a prerelease in our Ubuntu PPA by following the steps in the PPA section below on `develop` rather than on a tag. + This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle. +- [ ] Verify that the release tarball of `solc-js` works. + Bump version locally, add `soljson.js` from CI, build it, compare the file structure with the previous version, install it locally and try to use it. +- [ ] Review [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes) to make sure you don't repeat the same mistakes. ### Drafts At least a day before the release: - - [ ] Create a draft PR to sort the changelog. - - [ ] Create draft PRs to bump version in ``solidity`` and ``solc-js``. - **Note**: The ``solc-js`` PR won't pass CI checks yet because it depends on the soljson binary from ``solc-bin``. - - [ ] Create a draft of the release on github. - - [ ] Create a draft PR to update soliditylang.org. - - [ ] Create drafts of blog posts. - - [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements. +- [ ] Create a draft PR to sort the changelog. +- [ ] Create draft PRs to bump version in `solidity` and `solc-js`. + **Note**: The `solc-js` PR won't pass CI checks yet because it depends on the soljson binary from `solc-bin`. +- [ ] Create a draft of the release on github. +- [ ] Create a draft PR to update soliditylang.org. +- [ ] Create drafts of blog posts. +- [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements. ### Blog Post - - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Releases`` category and explain some of the new features or concepts. - - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Security Alerts`` category in case of important bug(s). - - [ ] Get the posts reviewed and approved **before the release starts**. +- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the `Releases` category and explain some of the new features or concepts. +- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the `Security Alerts` category in case of important bug(s). +- [ ] Get the posts reviewed and approved **before the release starts**. ### Changelog - - [ ] 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``. - Make sure that the resulting ``bugs_by_version.json`` has a new, empty entry for the new version. - - [ ] Commit changes, create a pull request and wait for the tests. Then merge it. - - [ ] Copy the changelog into the release blog post. +- [ ] 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`. + Make sure that the resulting `bugs_by_version.json` has a new, empty entry for the new version. +- [ ] Commit changes, create a pull request and wait for the tests. Then merge it. +- [ ] Copy the changelog into the release blog post. ### Create the Release - - [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new). - Set the target to the ``develop`` branch and the tag to the new version, e.g. ``v0.8.5``. - Include the following warning: ``**The release is still in progress. You may see broken links and binaries may not yet be available from all sources.**``. - Do not publish it yet - click the ``Save draft`` button instead. - - [ ] Thank voluntary contributors in the GitHub release notes. - Use ``scripts/list_contributors.sh v`` to get initial list of names. - Remove different variants of the same name manually before using the output. - - [ ] Check that all tests on the latest commit in ``develop`` are green. - - [ ] Click the ``Publish release`` button on the release page, creating the tag. - **Important: Must not be done before all the PRs, including changelog cleanup and date, are merged.** - - [ ] Wait for the CI runs on the tag itself. +- [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new). + Set the target to the `develop` branch and the tag to the new version, e.g. `v0.8.5`. + Include the following warning: `**The release is still in progress. You may see broken links and binaries may not yet be available from all sources.**`. + Do not publish it yet - click the `Save draft` button instead. +- [ ] Thank voluntary contributors in the GitHub release notes. + Use `scripts/list_contributors.sh v` to get initial list of names. + Remove different variants of the same name manually before using the output. +- [ ] Check that all tests on the latest commit in `develop` are green. +- [ ] Click the `Publish release` button on the release page, creating the tag. + **Important: Must not be done before all the PRs, including changelog cleanup and date, are merged.** +- [ ] Wait for the CI runs on the tag itself. ### Upload Release Artifacts and Publish Binaries - - [ ] Switch to the tag that archives have to be created for. - - [ ] Create the ``prerelease.txt`` file: (``echo -n > prerelease.txt``). - - [ ] Run ``scripts/create_source_tarball.sh`` while being on the tag to create the source tarball. This will create the tarball in a directory called ``upload``. - - [ ] Take the tarball from the upload directory (its name should be ``solidity_x.x.x.tar.gz``, otherwise ``prerelease.txt`` was missing in the step before) and upload the source tarball to the release page. - - [ ] Take the ``github-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to the release page. - Make sure it contains four binaries: ``solc-windows.exe``, ``solc-macos``, ``solc-static-linux`` and ``soljson.js``. - - [ ] Take the ``solc-bin-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to solc-bin. - - [ ] Run ``npm install`` if you've got a clean checkout of the solc-bin repo. - - [ ] Run ``npm run update -- --reuse-hashes`` in ``solc-bin`` and verify that the script has updated ``list.js``, ``list.txt`` and ``list.json`` files correctly and that symlinks to the new release have been added in ``solc-bin/wasm/`` and ``solc-bin/emscripten-wasm32/``. - - [ ] Create a pull request in solc-bin and merge. +- [ ] Switch to the tag that archives have to be created for. +- [ ] Create the `prerelease.txt` file: (`echo -n > prerelease.txt`). +- [ ] Run `scripts/create_source_tarball.sh` while being on the tag to create the source tarball. This will create the tarball in a directory called `upload`. +- [ ] Take the tarball from the upload directory (its name should be `solidity_x.x.x.tar.gz`, otherwise `prerelease.txt` was missing in the step before) and upload the source tarball to the release page. +- [ ] Take the `github-binaries.tar` tarball from `c_release_binaries` run of the tagged commit in circle-ci and add all binaries from it to the release page. + Make sure it contains four binaries: `solc-windows.exe`, `solc-macos`, `solc-static-linux` and `soljson.js`. +- [ ] Take the `solc-bin-binaries.tar` tarball from `c_release_binaries` run of the tagged commit in circle-ci and add all binaries from it to solc-bin. +- [ ] Run `npm install` if you've got a clean checkout of the solc-bin repo. +- [ ] Run `npm run update -- --reuse-hashes` in `solc-bin` and verify that the script has updated `list.js`, `list.txt` and `list.json` files correctly and that symlinks to the new release have been added in `solc-bin/wasm/` and `solc-bin/emscripten-wasm32/`. +- [ ] Create a pull request in solc-bin and merge. ### Homebrew and MacOS - - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in the [``solidity`` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/s/solidity.rb). +- [ ] Update the version and the hash (`sha256sum solidity_$VERSION.tar.gz`) in the [`solidity` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/s/solidity.rb). ### Docker - - [ ] Make sure ``docker-buildx`` is installed. - - [ ] Run ``./scripts/docker_deploy_manual.sh v$VERSION``. +- [ ] Make sure `docker-buildx` is installed. +- [ ] Run `./scripts/docker_deploy_manual.sh v$VERSION`. ### PPA - - [ ] Create ``.release_ppa_auth`` at the root of your local Solidity checkout and set ``LAUNCHPAD_EMAIL`` and ``LAUNCHPAD_KEYID`` to your key's email and key id. - - [ ] Double-check that the ``DISTRIBUTIONS`` list in ``scripts/release_ppa.sh`` and ``scripts/deps-ppa/static_z3.sh`` contains the most recent versions of Ubuntu. - - [ ] Make sure the [``~ethereum/cpp-build-deps`` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains ``libz3-static-dev`` builds for all current versions of Ubuntu. - Note that it may be included in the ``z3-static`` multipackage (follow the ``View package details`` link to check). - If not present, run ``scripts/deps-ppa/static_z3.sh`` and wait for the builds to succeed before continuing. - - [ ] Run ``scripts/release_ppa.sh v$VERSION`` to create the PPA release. - This will create a single package containing static binary for older Ubuntu versions in the [``~ethereum/ethereum-static`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) - and separate packages with dynamically-linked binaries for recent versions (those listed in ``DISTRIBUTIONS``) in the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum). - - [ ] Wait for the build to be finished and published for *all architectures* (currently we only build for ``amd64``, but we may add ``arm`` in the future). - **SERIOUSLY: DO NOT PROCEED EARLIER!!!** - - [ ] *After* the package with the static build is *published*, use it to create packages for older Ubuntu versions. - Copy the static package to the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum) - for the destination series ``Trusty``, ``Xenial``, ``Bionic``, and ``Focal`` - while selecting ``Copy existing binaries``. +- [ ] Create `.release_ppa_auth` at the root of your local Solidity checkout and set `LAUNCHPAD_EMAIL` and `LAUNCHPAD_KEYID` to your key's email and key id. +- [ ] Double-check that the `DISTRIBUTIONS` list in `scripts/release_ppa.sh` and `scripts/deps-ppa/static_z3.sh` contains the most recent versions of Ubuntu. +- [ ] Make sure the [`~ethereum/cpp-build-deps` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains `libz3-static-dev` builds for all current versions of Ubuntu. + Note that it may be included in the `z3-static` multipackage (follow the `View package details` link to check). + If not present, run `scripts/deps-ppa/static_z3.sh` and wait for the builds to succeed before continuing. +- [ ] Run `scripts/release_ppa.sh v$VERSION` to create the PPA release. + This will create a single package containing static binary for older Ubuntu versions in the [`~ethereum/ethereum-static` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) + and separate packages with dynamically-linked binaries for recent versions (those listed in `DISTRIBUTIONS`) in the [`~ethereum/ethereum` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum). +- [ ] Wait for the build to be finished and published for *all architectures* (currently we only build for `amd64`, but we may add `arm` in the future). + **SERIOUSLY: DO NOT PROCEED EARLIER!!!** +- [ ] *After* the package with the static build is *published*, use it to create packages for older Ubuntu versions. + Copy the static package to the [`~ethereum/ethereum` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum) + for the destination series `Trusty`, `Xenial`, `Bionic`, and `Focal` + while selecting `Copy existing binaries`. ### Release solc-js - - [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway. - - [ ] Increment the version number, create a pull request for that, merge it after tests succeeded. - - [ ] Create a tag using ``git tag --annotate v$VERSION`` and push it with ``git push --tags``. - - [ ] Wait for the CI runs on the tag itself. - - [ ] Take the ``solc-x.y.z.tgz`` artifact from ``build-package`` run on the tagged commit in circle-ci. - Inspect the tarball to ensure that it contains an up-to-date compiler binary (``soljson.js``). - - [ ] Run ``npm publish solc-x.y.z.tgz`` to publish the newly created tarball. +- [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway. +- [ ] Increment the version number, create a pull request for that, merge it after tests succeeded. +- [ ] Create a tag using `git tag --annotate v$VERSION` and push it with `git push --tags`. +- [ ] Wait for the CI runs on the tag itself. +- [ ] Take the `solc-x.y.z.tgz` artifact from `build-package` run on the tagged commit in circle-ci. + Inspect the tarball to ensure that it contains an up-to-date compiler binary (`soljson.js`). +- [ ] Run `npm publish solc-x.y.z.tgz` to publish the newly created tarball. ### Post-release - - [ ] Make sure the documentation for the new release has been published successfully. - Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default. - - [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases). - - [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release. - - [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry. - - [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx). - - [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post. - - [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post. - - [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/). - - [ ] Share the announcement on the [Solidity forum](https://forum.soliditylang.org) in the ``Announcements`` category. - - [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696) - - [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) - - [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) - - [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes). - - [ ] Bump vendored dependencies. - - [ ] Lean back, wait for bug reports and repeat from step 1 :). +- [ ] Make sure the documentation for the new release has been published successfully. + Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default. +- [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases). +- [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release. +- [ ] Create a commit to increase the version number on `develop` in `CMakeLists.txt` and add a new skeleton changelog entry. +- [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx). +- [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post. +- [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post. +- [ ] Share the announcement on Reddit in [`/r/ethdev`](https://reddit.com/r/ethdev/), cross-posted to [`/r/ethereum`](https://reddit.com/r/ethereum/). +- [ ] Share the announcement on the [Solidity forum](https://forum.soliditylang.org) in the `Announcements` category. +- [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696) +- [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) +- [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) +- [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes). +- [ ] Bump vendored dependencies. +- [ ] Lean back, wait for bug reports and repeat from step 1 :). From 70d344a0e93b299b531cbde369713ae067567688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 14 Mar 2025 23:55:49 +0100 Subject: [PATCH 006/121] Remove double backticks from CODING_STYLE.md --- CODING_STYLE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODING_STYLE.md b/CODING_STYLE.md index 2305ae1ec752..b70126d91643 100644 --- a/CODING_STYLE.md +++ b/CODING_STYLE.md @@ -110,9 +110,9 @@ Use `solAssert` and `solUnimplementedAssert` generously to check assumptions tha 4. Favour declarations close to use; do not habitually declare at top of scope ala C. 5. Pass non-trivial parameters as const reference, unless the data is to be copied into the function, then either pass by const reference or by value and use std::move. 6. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments. -7. Use parameters of pointer type only if ``nullptr`` is a valid argument, use references otherwise. Often, ``std::optional`` is better suited than a raw pointer. +7. Use parameters of pointer type only if `nullptr` is a valid argument, use references otherwise. Often, `std::optional` is better suited than a raw pointer. 8. Never use a macro where adequate non-preprocessor C++ can be written. -9. Only use ``auto`` if the type is very long and rather irrelevant. +9. Only use `auto` if the type is very long and rather irrelevant. 10. Do not pass bools: prefer enumerations instead. 11. Prefer enum class to straight enum. 12. Always initialize POD variables, even if their value is overwritten later. From 145e281fac9369c920c9628fe4a967f7b71e9193 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 14:13:23 +0100 Subject: [PATCH 007/121] Name dependent CSE bug: Compare ASM only --- test/cmdlineTests/~name_dependent_cse_bug/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cmdlineTests/~name_dependent_cse_bug/test.sh b/test/cmdlineTests/~name_dependent_cse_bug/test.sh index 96c3ac23ed97..710e82b1e7a0 100755 --- a/test/cmdlineTests/~name_dependent_cse_bug/test.sh +++ b/test/cmdlineTests/~name_dependent_cse_bug/test.sh @@ -19,7 +19,7 @@ function assemble_with_variable_name { local variable_name="$2" sed -e "s|__placeholder__|${variable_name}|g" "$input_file" | msg_on_error --no-stderr \ - "$SOLC" --strict-assembly - --optimize --debug-info none | + "$SOLC" --strict-assembly - --optimize --debug-info none --asm | stripCLIDecorations } From 74cd757be52c658a8eef7a81c62d364ee1921652 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 08:52:34 +0100 Subject: [PATCH 008/121] SSACFG Builder: Improve function call visitor --- .../evm/SSAControlFlowGraphBuilder.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index bf8cfd92a802..69e9e3052104 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -548,21 +548,22 @@ void SSAControlFlowGraphBuilder::assign(std::vector SSAControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) { bool canContinue = true; - SSACFG::Operation operation = [&](){ - if (BuiltinFunction const* builtin = resolveBuiltinFunction(_call.functionName, m_dialect)) + SSACFG::Operation operation = std::visit(util::GenericVisitor{ + [&](BuiltinName const& _builtinName) { - SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, *builtin, _call}, {}}; + auto const& builtin = m_dialect.builtin(_builtinName.handle); + SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, builtin, _call}, {}}; for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtin->literalArgument(idx).has_value()) + if (!builtin.literalArgument(idx).has_value()) result.inputs.emplace_back(std::visit(*this, arg)); - for (size_t i = 0; i < builtin->numReturns; ++i) + for (size_t i = 0; i < builtin.numReturns; ++i) result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); - canContinue = builtin->controlFlowSideEffects.canContinue; + canContinue = builtin.controlFlowSideEffects.canContinue; return result; - } - else + }, + [&](Identifier const& _identifier) { - YulName const functionName{resolveFunctionName(_call.functionName, m_dialect)}; + YulName const& functionName = _identifier.name; Scope::Function const& function = lookupFunction(functionName); auto const* definition = findFunctionDefinition(&function); yulAssert(definition); @@ -574,7 +575,7 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); return result; } - }(); + }, _call.functionName); auto results = operation.outputs; currentBlock().operations.emplace_back(std::move(operation)); if (!canContinue) From 25463c564dc18cb98750e49d227901087a32940b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 14 Feb 2025 12:40:18 +0100 Subject: [PATCH 009/121] SMTChecker: Fix analysis for selected contracts Previously, when a contract was selected for analysis, the analysis was incorrect. There were two issues. First, the contracts in the same file were considered as entry points even though they were not selected for analysis. Second, the contracts in a different file were mostly ignored, resulting in unsoundness when an external call was made to such a contract in trusted mode. The solution to the above problems is to always create representation of all contracts (in case they are called from the selected contract), but create verification targets only for the selected contracts. --- Changelog.md | 1 + libsolidity/formal/BMC.cpp | 2 +- libsolidity/formal/CHC.cpp | 26 ++++---- libsolidity/formal/ModelCheckerSettings.cpp | 2 +- libsolidity/formal/SMTEncoder.cpp | 13 ++-- libsolidity/formal/SMTEncoder.h | 11 ++-- .../err | 26 -------- .../model_checker_contracts_only_one/err | 2 +- .../output.json | 66 ------------------- .../output.json | 4 +- .../output.json | 4 +- test/libsolidity/SMTCheckerTest.cpp | 11 +++- ...ternal_call_from_constructor_1_trusted.sol | 5 +- ...ternal_call_from_constructor_3_trusted.sol | 5 +- ...lled_from_selection_with_trusted_calls.sol | 11 ++++ ...selected_and_not_called_from_selection.sol | 9 +++ ...selected_and_not_called_from_selection.sol | 13 ++++ ...selected_and_not_called_from_selection.sol | 11 ++++ 18 files changed, 94 insertions(+), 128 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol create mode 100644 test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol create mode 100644 test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol create mode 100644 test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol diff --git a/Changelog.md b/Changelog.md index 47334fd3dacd..3e423c838b67 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: +* SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`. ### 0.8.29 (2025-03-12) diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index e5521b816582..6dcd856ee2af 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -1068,7 +1068,7 @@ void BMC::addVerificationTarget( Expression const* _expression ) { - if (!m_settings.targets.has(_type) || (m_currentContract && !shouldAnalyze(*m_currentContract))) + if (!m_settings.targets.has(_type) || (m_currentContract && !shouldAnalyzeVerificationTargetsFor(*m_currentContract))) return; BMCVerificationTarget target{ diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index c313ae54e1ae..bab340051f82 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -89,7 +89,7 @@ void CHC::analyze(SourceUnit const& _source) " If you wish to use Eldarica, please enable Eldarica only." ); - if (!shouldAnalyze(_source)) + if (!shouldAnalyzeVerificationTargetsFor(_source)) return; resetSourceAnalysis(); @@ -131,7 +131,7 @@ std::vector CHC::unhandledQueries() const bool CHC::visit(ContractDefinition const& _contract) { - if (!shouldAnalyze(_contract)) + if (!shouldEncode(_contract)) return false; // Raises UnimplementedFeatureError in the presence of transient storage variables @@ -152,7 +152,7 @@ bool CHC::visit(ContractDefinition const& _contract) void CHC::endVisit(ContractDefinition const& _contract) { - if (!shouldAnalyze(_contract)) + if (!shouldEncode(_contract)) return; for (auto base: _contract.annotation().linearizedBaseContracts) @@ -239,15 +239,14 @@ void CHC::endVisit(ContractDefinition const& _contract) setCurrentBlock(*m_constructorSummaries.at(&_contract)); solAssert(&_contract == m_currentContract, ""); - if (shouldAnalyze(_contract)) - { - auto constructor = _contract.constructor(); - auto txConstraints = state().txTypeConstraints(); - if (!constructor || !constructor->isPayable()) - txConstraints = txConstraints && state().txNonPayableConstraint(); + smtAssert(shouldEncode(_contract)); + auto constructor = _contract.constructor(); + auto txConstraints = state().txTypeConstraints(); + if (!constructor || !constructor->isPayable()) + txConstraints = txConstraints && state().txNonPayableConstraint(); + connectBlocks(m_currentBlock, interface(), txConstraints && errorFlag().currentValue() == 0); + if (shouldAnalyzeVerificationTargetsFor(_contract)) m_queryPlaceholders[&_contract].push_back({txConstraints, errorFlag().currentValue(), m_currentBlock}); - connectBlocks(m_currentBlock, interface(), txConstraints && errorFlag().currentValue() == 0); - } solAssert(m_scopes.back() == &_contract, ""); m_scopes.pop_back(); @@ -338,7 +337,7 @@ void CHC::endVisit(FunctionDefinition const& _function) !_function.isConstructor() && _function.isPublic() && contractFunctions(*m_currentContract).count(&_function) && - shouldAnalyze(*m_currentContract) + shouldEncode(*m_currentContract) ) { defineExternalFunctionInterface(_function, *m_currentContract); @@ -349,8 +348,9 @@ void CHC::endVisit(FunctionDefinition const& _function) auto ifacePre = smt::interfacePre(*m_interfaces.at(m_currentContract), *m_currentContract, m_context); auto sum = externalSummary(_function); - m_queryPlaceholders[&_function].push_back({sum, errorFlag().currentValue(), ifacePre}); connectBlocks(ifacePre, interface(), sum && errorFlag().currentValue() == 0); + if (shouldAnalyzeVerificationTargetsFor(*m_currentContract)) + m_queryPlaceholders[&_function].push_back({sum, errorFlag().currentValue(), ifacePre}); } m_currentFunction = nullptr; diff --git a/libsolidity/formal/ModelCheckerSettings.cpp b/libsolidity/formal/ModelCheckerSettings.cpp index ed4d5ce204c0..ffeedfe3ace0 100644 --- a/libsolidity/formal/ModelCheckerSettings.cpp +++ b/libsolidity/formal/ModelCheckerSettings.cpp @@ -123,7 +123,7 @@ std::optional ModelCheckerContracts::fromString(std::stri { auto&& names = sourceContract | ranges::views::split(':') | ranges::to>(); if (names.size() != 2 || names.at(0).empty() || names.at(1).empty()) - return {}; + return std::nullopt; chosen[names.at(0)].insert(names.at(1)); } diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index a0b71f5941a9..740af9382b88 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -1092,19 +1092,24 @@ void SMTEncoder::visitPublicGetter(FunctionCall const& _funCall) } } -bool SMTEncoder::shouldAnalyze(SourceUnit const& _source) const +bool SMTEncoder::shouldEncode(ContractDefinition const& _contract) const +{ + return _contract.canBeDeployed(); +} + +bool SMTEncoder::shouldAnalyzeVerificationTargetsFor(SourceUnit const& _source) const { return m_settings.contracts.isDefault() || m_settings.contracts.has(*_source.annotation().path); } -bool SMTEncoder::shouldAnalyze(ContractDefinition const& _contract) const +bool SMTEncoder::shouldAnalyzeVerificationTargetsFor(ContractDefinition const& _contract) const { - if (!_contract.canBeDeployed()) + if (!shouldEncode(_contract)) return false; return m_settings.contracts.isDefault() || - m_settings.contracts.has(_contract.sourceUnitName()); + m_settings.contracts.has(_contract.sourceUnitName(), _contract.name()); } void SMTEncoder::visitTypeConversion(FunctionCall const& _funCall) diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index f926a0d0fc80..5bfb70d8126d 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -238,11 +238,12 @@ class SMTEncoder: public ASTConstVisitor void visitFunctionIdentifier(Identifier const& _identifier); virtual void visitPublicGetter(FunctionCall const& _funCall); - /// @returns true if @param _contract is set for analysis in the settings - /// and it is not abstract. - bool shouldAnalyze(ContractDefinition const& _contract) const; - /// @returns true if @param _source is set for analysis in the settings. - bool shouldAnalyze(SourceUnit const& _source) const; + /// @returns true if symbolic representation of @param _contract is required for verification + bool shouldEncode(ContractDefinition const& _contract) const; + /// @returns true if the verification targets of @param _contract are actually selected for verification + bool shouldAnalyzeVerificationTargetsFor(ContractDefinition const& _contract) const; + /// @returns true if we should descend into @param _source to look for contracts that should be verified + bool shouldAnalyzeVerificationTargetsFor(SourceUnit const& _source) const; /// @returns the state variable returned by a public getter if /// @a _expr is a call to a public getter, diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err index 00b97763f340..6326537e928c 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err +++ b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err @@ -1,27 +1 @@ Warning: Requested contract "C" does not exist in source "model_checker_contracts_inexistent_contract/input.sol". - -Warning: CHC: Assertion violation happens here. -Counterexample: - -x = 0 - -Transaction trace: -B.constructor() -B.f(0) - --> model_checker_contracts_inexistent_contract/input.sol:5:3: - | -5 | assert(x > 0); - | ^^^^^^^^^^^^^ - -Warning: CHC: Assertion violation happens here. -Counterexample: - -y = 0 - -Transaction trace: -A.constructor() -A.g(0) - --> model_checker_contracts_inexistent_contract/input.sol:10:3: - | -10 | assert(y > 0); - | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_contracts_only_one/err b/test/cmdlineTests/model_checker_contracts_only_one/err index 2088e19c7a2f..9c8ade6931c3 100644 --- a/test/cmdlineTests/model_checker_contracts_only_one/err +++ b/test/cmdlineTests/model_checker_contracts_only_one/err @@ -4,7 +4,7 @@ Counterexample: x = 0 Transaction trace: -B.constructor() +A.constructor() B.f(0) --> model_checker_contracts_only_one/input.sol:5:3: | diff --git a/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json b/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json index 22d5f32de32b..c6bde90dfbaa 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json @@ -9,72 +9,6 @@ "message": "Requested contract \"C\" does not exist in source \"Source\".", "severity": "warning", "type": "Warning" - }, - { - "component": "general", - "errorCode": "6328", - "formattedMessage": "Warning: CHC: Assertion violation happens here. -Counterexample: - -y = 0 - -Transaction trace: -B.constructor() -B.g(0) - --> Source:5:7: - | -5 | \t\t\t\t\t\tassert(y > 0); - | \t\t\t\t\t\t^^^^^^^^^^^^^ - -", - "message": "CHC: Assertion violation happens here. -Counterexample: - -y = 0 - -Transaction trace: -B.constructor() -B.g(0)", - "severity": "warning", - "sourceLocation": { - "end": 137, - "file": "Source", - "start": 124 - }, - "type": "Warning" - }, - { - "component": "general", - "errorCode": "6328", - "formattedMessage": "Warning: CHC: Assertion violation happens here. -Counterexample: - -x = 0 - -Transaction trace: -A.constructor() -A.f(0) - --> Source:10:7: - | -10 | \t\t\t\t\t\tassert(x > 0); - | \t\t\t\t\t\t^^^^^^^^^^^^^ - -", - "message": "CHC: Assertion violation happens here. -Counterexample: - -x = 0 - -Transaction trace: -A.constructor() -A.f(0)", - "severity": "warning", - "sourceLocation": { - "end": 231, - "file": "Source", - "start": 218 - }, - "type": "Warning" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json b/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json index fe287f833637..f568de16044b 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json @@ -9,7 +9,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0) --> Source:5:7: | @@ -23,7 +23,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0)", "severity": "warning", "sourceLocation": { diff --git a/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json b/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json index e9fc1b4cf6b5..a7ca17b4f5b4 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json @@ -9,7 +9,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0) --> Source:5:7: | @@ -23,7 +23,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0)", "severity": "warning", "sourceLocation": { diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index d8843e0d3a1e..ce099091f69c 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -32,8 +32,17 @@ SMTCheckerTest::SMTCheckerTest(std::string const& _filename): universalCallback(nullptr, smtCommand) { auto contract = m_reader.stringSetting("SMTContract", ""); - if (!contract.empty()) + auto maybeContracts = ModelCheckerContracts::fromString(contract); + auto isValidContractName = [](std::string const& _name) + { + return !_name.empty() && _name.find_first_of(" \t\n\r:,") == std::string::npos; + }; + if (maybeContracts) + m_modelCheckerSettings.contracts = *maybeContracts; + else if (isValidContractName(contract)) m_modelCheckerSettings.contracts.contracts[""] = {contract}; + else + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid contract specified in SMTContract setting.")); auto extCallsMode = ModelCheckerExtCalls::fromString(m_reader.stringSetting("SMTExtCalls", "untrusted")); if (extCallsMode) diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol index 6f2b717b5e87..051215bb102d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol @@ -1,6 +1,6 @@ contract State { function f(uint _x) public pure returns (uint) { - assert(_x < 100); // should fail + assert(_x < 100); // should hold when analyzing only contract C (can fail only when analyzing State as standalone contract) return _x; } } @@ -18,5 +18,4 @@ contract C { // SMTExtCalls: trusted // SMTIgnoreInv: yes // ---- -// Warning 6328: (69-85): 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. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol index 590664055d6b..0f22100d696d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol @@ -1,6 +1,6 @@ contract State { function f(uint _x) public pure returns (uint) { - assert(_x < 100); // should fail + assert(_x < 100); // should hold when analyzing only contract C (can fail only when analyzing State as standalone contract) return _x; } } @@ -21,5 +21,4 @@ contract C { // SMTEngine: all // SMTExtCalls: trusted // ---- -// Warning 6328: (69-85): 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. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol new file mode 100644 index 000000000000..9389f7d93866 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol @@ -0,0 +1,11 @@ +==== Source: A.sol ==== +contract A { function a() pure public { assert(false); } } +==== Source: B.sol ==== +import "A.sol"; +contract B { function b(A a) pure public { a.a(); } } +// ==== +// SMTContract: B.sol:B +// SMTEngine: chc +// SMTExtCalls: trusted +// ---- +// Warning 6328: (A.sol:40-53): CHC: Assertion violation happens here.\nCounterexample:\n\na = 0\n\nTransaction trace:\nB.constructor()\nB.b(0)\n A.a() -- trusted external call diff --git a/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol new file mode 100644 index 000000000000..a7c472bbcd1a --- /dev/null +++ b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol @@ -0,0 +1,9 @@ +==== Source: A.sol ==== +contract A { function a() pure public { assert(false); } } +==== Source: B.sol ==== +import "A.sol"; +contract B { function b() pure public { } } +// ==== +// SMTContract: B.sol:B +// SMTEngine: chc +// ---- diff --git a/test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol b/test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol new file mode 100644 index 000000000000..29d8017cc075 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol @@ -0,0 +1,13 @@ +contract B { + constructor() { fail(); } + + function fail() pure internal { assert(false); } +} + +contract A { + function safe() pure public { } +} +// ==== +// SMTContract: A +// SMTEngine: chc +// ---- diff --git a/test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol b/test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol new file mode 100644 index 000000000000..f9fcdbb18e7c --- /dev/null +++ b/test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol @@ -0,0 +1,11 @@ +contract B { + function fail() pure public { assert(false); } +} + +contract A { + function safe() pure public { } +} +// ==== +// SMTContract: A +// SMTEngine: chc +// ---- From f2c9eecb46107a6caa1a9604fec7613b027a3d4a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 08:59:15 +0100 Subject: [PATCH 010/121] Yul Disambiguator: Don't check for builtins when translating identifiers --- libyul/optimiser/Disambiguator.cpp | 6 +++--- libyul/optimiser/Disambiguator.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libyul/optimiser/Disambiguator.cpp b/libyul/optimiser/Disambiguator.cpp index 55219f6eae37..343feb0be379 100644 --- a/libyul/optimiser/Disambiguator.cpp +++ b/libyul/optimiser/Disambiguator.cpp @@ -30,15 +30,15 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; -YulName Disambiguator::translateIdentifier(YulName _originalName) +YulName Disambiguator::translateIdentifier(YulName const _originalName) { - if (m_dialect.findBuiltin(_originalName.str()) || m_externallyUsedIdentifiers.count(_originalName)) + if (m_externallyUsedIdentifiers.contains(_originalName)) return _originalName; assertThrow(!m_scopes.empty() && m_scopes.back(), OptimizerException, ""); Scope::Identifier const* id = m_scopes.back()->lookup(_originalName); assertThrow(id, OptimizerException, ""); - if (!m_translations.count(id)) + if (!m_translations.contains(id)) m_translations[id] = m_nameDispenser.newName(_originalName); return m_translations.at(id); } diff --git a/libyul/optimiser/Disambiguator.h b/libyul/optimiser/Disambiguator.h index 36d178b086c1..7ff186f0a8c7 100644 --- a/libyul/optimiser/Disambiguator.h +++ b/libyul/optimiser/Disambiguator.h @@ -56,7 +56,7 @@ class Disambiguator: public ASTCopier void leaveScope(Block const& _block) override; void enterFunction(FunctionDefinition const& _function) override; void leaveFunction(FunctionDefinition const& _function) override; - YulName translateIdentifier(YulName _name) override; + YulName translateIdentifier(YulName _originalName) override; void enterScopeInternal(Scope& _scope); void leaveScopeInternal(Scope& _scope); From 8f38f2304a69ad73b3800c5d552c2bda9dd8afff Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 19 Mar 2025 15:45:17 +0100 Subject: [PATCH 011/121] Peephole optimiser: Replace apply methods recursion by folding expression --- libevmasm/PeepholeOptimiser.cpp | 67 +++++++++++++++------------------ 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 879f5b3272dc..cc22db9fa2fd 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -690,16 +690,12 @@ struct DeduplicateNextTagSize1 : SimplePeepholeOptimizerMethod +void applyMethods(OptimiserState& _state) { - assertThrow(false, OptimizerException, "Peephole optimizer failed to apply identity."); -} - -template -void applyMethods(OptimiserState& _state, Method, OtherMethods... _other) -{ - if (!Method::apply(_state)) - applyMethods(_state, _other...); + bool continueWithNextMethod = true; + ((continueWithNextMethod && (continueWithNextMethod &= !Method::apply(_state))), ...); + assertThrow(!continueWithNextMethod, OptimizerException, "Peephole optimizer failed to apply identity."); } size_t numberOfPops(AssemblyItems const& _items) @@ -721,33 +717,32 @@ bool PeepholeOptimiser::optimise() auto const approx = evmasm::Precision::Approximate; OptimiserState state {m_items, 0, back_inserter(m_optimisedItems), m_evmVersion}; while (state.i < m_items.size()) - applyMethods( - state, - PushPop(), - OpPop(), - OpStop(), - OpReturnRevert(), - DoublePush(), - DoubleSwap(), - CommutativeSwap(), - SwapComparison(), - DupSwap(), - IsZeroIsZeroJumpI(), - IsZeroIsZeroRJumpI(), // EOF specific - EqIsZeroJumpI(), - EqIsZeroRJumpI(), // EOF specific - DoubleJump(), - DoubleRJump(), // EOF specific - JumpToNext(), - RJumpToNext(), // EOF specific - UnreachableCode(), - DeduplicateNextTagSize3(), - DeduplicateNextTagSize2(), - DeduplicateNextTagSize1(), - TagConjunctions(), - TruthyAnd(), - Identity() - ); + applyMethods< + PushPop, + OpPop, + OpStop, + OpReturnRevert, + DoublePush, + DoubleSwap, + CommutativeSwap, + SwapComparison, + DupSwap, + IsZeroIsZeroJumpI, + IsZeroIsZeroRJumpI, // EOF specific + EqIsZeroJumpI, + EqIsZeroRJumpI, // EOF specific + DoubleJump, + DoubleRJump, // EOF specific + JumpToNext, + RJumpToNext, // EOF specific + UnreachableCode, + DeduplicateNextTagSize3, + DeduplicateNextTagSize2, + DeduplicateNextTagSize1, + TagConjunctions, + TruthyAnd, + Identity + >(state); if (m_optimisedItems.size() < m_items.size() || ( m_optimisedItems.size() == m_items.size() && ( evmasm::bytesRequired(m_optimisedItems, 3, m_evmVersion, approx) < evmasm::bytesRequired(m_items, 3, m_evmVersion, approx) || From 098b854ce59393a1ef48e06de6b031a793486508 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:38:07 +0100 Subject: [PATCH 012/121] IRGeneratorForStatements does not check for builtin when mangling user identifiers --- .../codegen/ir/IRGeneratorForStatements.cpp | 21 +++++++------------ .../codegen/IRGeneratorForStatements.cpp | 11 +++------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index c716c43a6070..5902cfef68b6 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -63,8 +63,8 @@ struct CopyTranslate: public yul::ASTCopier { using ExternalRefsMap = std::map; - CopyTranslate(yul::Dialect const& _dialect, IRGenerationContext& _context, ExternalRefsMap const& _references): - m_dialect(_dialect), m_context(_context), m_references(_references) {} + CopyTranslate(IRGenerationContext& _context, ExternalRefsMap const& _references): + m_context(_context), m_references(_references) {} using ASTCopier::operator(); @@ -80,14 +80,11 @@ struct CopyTranslate: public yul::ASTCopier yul::YulName translateIdentifier(yul::YulName _name) override { - // Strictly, the dialect used by inline assembly (m_dialect) could be different - // from the Yul dialect we are compiling to. So we are assuming here that the builtin - // functions are identical. This should not be a problem for now since everything - // is EVM anyway. - if (m_dialect.findBuiltin(_name.str())) - return _name; - else - return yul::YulName{"usr$" + _name.str()}; + // Strictly, the dialect used by inline assembly could be different + // from the Yul dialect we are compiling to. By only translating `YulName`s which correspond to Identifiers, + // we are implicitly excluding builtins together with the assumption, that numerical builtin handles + // stay identical. Special care has to be taken, that these numerical handles stay consistent. + return yul::YulName{"usr$" + _name.str()}; } yul::Identifier translate(yul::Identifier const& _identifier) override @@ -209,8 +206,6 @@ struct CopyTranslate: public yul::ASTCopier return yul::Identifier{_identifier.debugData, yul::YulName{value}}; } - - yul::Dialect const& m_dialect; IRGenerationContext& m_context; ExternalRefsMap const& m_references; }; @@ -2294,7 +2289,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) setLocation(_inlineAsm); if (*_inlineAsm.annotation().hasMemoryEffects && !_inlineAsm.annotation().markedMemorySafe) m_context.setMemoryUnsafeInlineAssemblySeen(); - CopyTranslate bodyCopier{_inlineAsm.dialect(), m_context, _inlineAsm.annotation().externalReferences}; + CopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences}; yul::Statement modified = bodyCopier(_inlineAsm.operations().root()); diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index 80c442b88146..14aef1107dd3 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -54,9 +54,8 @@ struct CopyTranslate: public yul::ASTCopier { CopyTranslate( IRGenerationContext const& _context, - yul::Dialect const& _dialect, std::map _references - ): m_context(_context), m_dialect(_dialect), m_references(std::move(_references)) {} + ): m_context(_context), m_references(std::move(_references)) {} using ASTCopier::operator(); @@ -72,10 +71,7 @@ struct CopyTranslate: public yul::ASTCopier yul::YulName translateIdentifier(yul::YulName _name) override { - if (m_dialect.findBuiltin(_name.str())) - return _name; - else - return yul::YulName{"usr$" + _name.str()}; + return yul::YulName{"usr$" + _name.str()}; } yul::Identifier translate(yul::Identifier const& _identifier) override @@ -106,7 +102,6 @@ struct CopyTranslate: public yul::ASTCopier } IRGenerationContext const& m_context; - yul::Dialect const& m_dialect; std::map m_references; }; @@ -129,7 +124,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tupleExpression) bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly) { - CopyTranslate bodyCopier{m_context, _assembly.dialect(), _assembly.annotation().externalReferences}; + CopyTranslate bodyCopier{m_context, _assembly.annotation().externalReferences}; yul::Statement modified = bodyCopier(_assembly.operations().root()); solAssert(std::holds_alternative(modified)); m_code << yul::AsmPrinter(_assembly.dialect())(std::get(modified)) << "\n"; From 08c9f535288b0d5a337c9dd416a47333791b41b9 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:41:03 +0100 Subject: [PATCH 013/121] AssemblyItem gets an optional instruction and the null-state is properly asserted --- libevmasm/AssemblyItem.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index b053c5b27598..8b65d77c91e9 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -105,7 +105,6 @@ class AssemblyItem explicit AssemblyItem(bytes _verbatimData, size_t _arguments, size_t _returnVariables): m_type(VerbatimBytecode), - m_instruction{}, m_verbatimBytecode{{_arguments, _returnVariables, std::move(_verbatimData)}}, m_debugData{langutil::DebugData::create()} {} @@ -195,7 +194,7 @@ class AssemblyItem /// @returns true if the item has m_instruction properly set. bool hasInstruction() const { - return + bool const shouldHaveInstruction = m_type == Operation || m_type == EOFCreate || m_type == ReturnContract || @@ -206,12 +205,14 @@ class AssemblyItem m_type == RetF || m_type == SwapN || m_type == DupN; + solAssert(shouldHaveInstruction == m_instruction.has_value()); + return shouldHaveInstruction; } /// @returns the instruction of this item (only valid if hasInstruction returns true) Instruction instruction() const { solAssert(hasInstruction()); - return m_instruction; + return *m_instruction; } /// @returns true if the type and data of the items are equal. @@ -323,7 +324,7 @@ class AssemblyItem size_t opcodeCount() const noexcept; AssemblyItemType m_type; - Instruction m_instruction; ///< Only valid if m_type == Operation + std::optional m_instruction; ///< Only valid for item types that represent a specific opcode std::shared_ptr m_data; ///< Only valid if m_type != Operation std::optional m_functionSignature; ///< Only valid if m_type == CallF or JumpF /// If m_type == VerbatimBytecode, this holds number of arguments, number of From dd03613b791b3d13d43b95e253c414eeeb27c35b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 20 Mar 2025 22:26:14 +0100 Subject: [PATCH 014/121] SMTChecker: Fix string literal to fixed bytes conversion with user-defined type --- Changelog.md | 1 + libsolidity/formal/SMTEncoder.cpp | 6 ++++-- ...tes_can_be_initialized_from_string_literal.sol | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol diff --git a/Changelog.md b/Changelog.md index 3e423c838b67..7efefca02d6a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: * SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`. +* SMTChecker: Fix internal compiler error when string literal is used to initialize user-defined type based on fixed bytes. ### 0.8.29 (2025-03-12) diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 740af9382b88..044ff61d8225 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -929,8 +929,10 @@ void SMTEncoder::visitAddMulMod(FunctionCall const& _funCall) void SMTEncoder::visitWrapUnwrap(FunctionCall const& _funCall) { auto const& args = _funCall.arguments(); - solAssert(args.size() == 1, ""); - defineExpr(_funCall, expr(*args.front())); + smtAssert(args.size() == 1, "Expected exactly one argument to wrap/unwrap"); + auto const& funType = dynamic_cast(*_funCall.expression().annotation().type); + auto const* argType = funType.parameterTypes().front(); + defineExpr(_funCall, expr(*args.front(), argType)); } void SMTEncoder::visitObjectCreation(FunctionCall const& _funCall) diff --git a/test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol b/test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol new file mode 100644 index 000000000000..fe64541f116e --- /dev/null +++ b/test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol @@ -0,0 +1,15 @@ +type MyBytes is bytes2; + +contract C { + MyBytes b = MyBytes.wrap("ab"); + + function check() view public { + assert(MyBytes.unwrap(b) == 0); // should fail + assert(MyBytes.unwrap(b) == 0x6162); // should hold + } +} +// ==== +// SMTEngine: chc +// ---- +// Warning 6328: (118-148): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.check() +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From d97d7115815314af238de314d710abd4a1aa6868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Wed, 26 Feb 2025 16:10:25 -0700 Subject: [PATCH 015/121] Update metadata docs for "libraries" and "compilationSettings" fields --- docs/metadata.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/metadata.rst b/docs/metadata.rst index 063936a9dcde..e5945ea5235c 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -124,11 +124,13 @@ explanatory purposes. "version": 1 // NatSpec version } }, - // Required: Compiler settings. Reflects the settings in the JSON input during compilation. - // Check the documentation of standard JSON input's "settings" field + // Required: Compiler settings. + // Reflects the settings in the JSON input during compilation, except the + // "compilationTarget" and the "libraries" fields. Check each field for details. + // See the standard JSON input's "settings" docs for the rest. "settings": { // Required for Solidity: File path and the name of the contract or library this - // metadata is created for. + // metadata is created for. Not a valid field in the standard JSON input settings. "compilationTarget": { "myDirectory/myFile.sol": "MyContract" }, @@ -137,8 +139,11 @@ explanatory purposes. // Optional: Only present if not null. "eofVersion": 1, // Required for Solidity: Addresses for libraries used. + // Note that metadata has a different format for "libraries" field than the standard JSON input. + // metadata format = { "MyLib.sol:MyLib": "0x123123..." } + // standard JSON input format = { "MyLib.sol": { "MyLib": "0x123123..." } } "libraries": { - "MyLib": "0x123123..." + "MyLib.sol:MyLib": "0x123123..." }, "metadata": { // Reflects the setting used in the input json, defaults to "true" From 2e33f2557c2c91b59c7d5593389992d7f09b26ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Wed, 26 Feb 2025 16:21:22 -0700 Subject: [PATCH 016/121] Update the metdata settings field to refer the rest of the settings to std-json --- docs/metadata.rst | 54 ++++++++++------------------------------------- 1 file changed, 11 insertions(+), 43 deletions(-) diff --git a/docs/metadata.rst b/docs/metadata.rst index e5945ea5235c..90513ee326de 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -124,20 +124,18 @@ explanatory purposes. "version": 1 // NatSpec version } }, - // Required: Compiler settings. - // Reflects the settings in the JSON input during compilation, except the - // "compilationTarget" and the "libraries" fields. Check each field for details. - // See the standard JSON input's "settings" docs for the rest. + // Required: Compiler settings. + // Reflects the settings in the JSON input during compilation, except: + // - Different format: "libraries" field + // - Added field in metadata.settings: "compilationTarget" + // - Not in metadata.settings: "stopAfter", "debug.debugInfo", "outputSelection" + // See the standard JSON input's "settings" field docs for the rest. "settings": { // Required for Solidity: File path and the name of the contract or library this - // metadata is created for. Not a valid field in the standard JSON input settings. + // metadata is created for. This field is not present in the standard JSON input settings. "compilationTarget": { "myDirectory/myFile.sol": "MyContract" }, - // Required for Solidity. - "evmVersion": "london", - // Optional: Only present if not null. - "eofVersion": 1, // Required for Solidity: Addresses for libraries used. // Note that metadata has a different format for "libraries" field than the standard JSON input. // metadata format = { "MyLib.sol:MyLib": "0x123123..." } @@ -145,40 +143,10 @@ explanatory purposes. "libraries": { "MyLib.sol:MyLib": "0x123123..." }, - "metadata": { - // Reflects the setting used in the input json, defaults to "true" - "appendCBOR": true, - // Reflects the setting used in the input json, defaults to "ipfs" - "bytecodeHash": "ipfs", - // Reflects the setting used in the input json, defaults to "false" - "useLiteralContent": true - }, - // Optional: Optimizer settings. The fields "enabled" and "runs" are deprecated - // and are only given for backward-compatibility. - "optimizer": { - "details": { - "constantOptimizer": false, - "cse": false, - "deduplicate": false, - // inliner defaults to "false" - "inliner": false, - // jumpdestRemover defaults to "true" - "jumpdestRemover": true, - "orderLiterals": false, - // peephole defaults to "true" - "peephole": true, - "yul": true, - // Optional: Only present if "yul" is "true" - "yulDetails": { - "optimizerSteps": "dhfoDgvulfnTUtnIf...", - "stackAllocation": false - } - }, - "enabled": true, - "runs": 500 - }, - // Required for Solidity: Sorted list of import remappings. - "remappings": [ ":g=/dir" ] + // ... + // ... + // ... + // The rest of the fields and their defaults same as in std JSON input. }, // Required: Compilation source files/source units, keys are file paths "sources": { From 1f044c153365955b48d19ae90fa8a57db359c870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Thu, 20 Mar 2025 10:29:03 +0100 Subject: [PATCH 017/121] Remove "sorted" in std-json remappings docs --- docs/using-the-compiler.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 4984d999df27..23e83baec4e6 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -279,7 +279,7 @@ Input Description { // Optional: Stop compilation after the given stage. Currently only "parsing" is valid here "stopAfter": "parsing", - // Optional: Sorted list of remappings + // Optional: List of remappings "remappings": [ ":g=/dir" ], // Optional: Optimizer settings "optimizer": { From 1ccea419e6770553f15ce80872be21165ba946c5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 14 Mar 2025 09:24:30 +0100 Subject: [PATCH 018/121] AsmAnalysis: Stronger use of fmt, refactor function call analysis --- libyul/AsmAnalysis.cpp | 272 ++++++++++++++++++++++------------------- libyul/AsmAnalysis.h | 19 +-- 2 files changed, 161 insertions(+), 130 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index b6ff862b3850..480373d13271 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -94,19 +94,28 @@ bool AsmAnalyzer::analyze(Block const& _block) AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Object const& _object) { yulAssert(_object.dialect()); - return analyzeStrictAssertCorrect(*_object.dialect(), _object.code()->root(), _object.summarizeStructure()); + return analyzeStrictAssertCorrect(*_object.dialect(), *_object.code(), _object.summarizeStructure()); +} + +AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( + Dialect const& _dialect, + AST const& _ast, + Object::Structure _objectStructure +) +{ + return analyzeStrictAssertCorrect(_dialect, _ast.root(), std::move(_objectStructure)); } AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( Dialect const& _dialect, Block const& _astRoot, - Object::Structure const _objectStructure + Object::Structure _objectStructure ) { ErrorList errorList; langutil::ErrorReporter errors(errorList); AsmAnalysisInfo analysisInfo; - bool success = yul::AsmAnalyzer( + bool success = AsmAnalyzer( analysisInfo, errors, _dialect, @@ -155,7 +164,7 @@ size_t AsmAnalyzer::operator()(Literal const& _literal) m_errorReporter.typeError( 3069_error, nativeLocationOf(_literal), - "String literal too long (" + std::to_string(formatLiteral(_literal, false /* _validated */ ).size()) + " > 32)" + fmt::format("String literal too long ({} > 32)", formatLiteral(_literal, false /* _validated */ ).size()) ); } else if (_literal.kind == LiteralKind::Number && _literal.value.hint() && bigint(*_literal.value.hint()) > u256(-1)) @@ -170,7 +179,7 @@ size_t AsmAnalyzer::operator()(Literal const& _literal) size_t AsmAnalyzer::operator()(Identifier const& _identifier) { - yulAssert(!_identifier.name.empty(), ""); + yulAssert(!_identifier.name.empty()); auto watcher = m_errorReporter.errorWatcher(); if (m_currentScope->lookup(_identifier.name, GenericVisitor{ @@ -180,7 +189,7 @@ size_t AsmAnalyzer::operator()(Identifier const& _identifier) m_errorReporter.declarationError( 4990_error, nativeLocationOf(_identifier), - "Variable " + _identifier.name.str() + " used before it was declared." + fmt::format("Variable {} used before it was declared.", _identifier.name.str()) ); }, [&](Scope::Function const&) @@ -188,14 +197,15 @@ size_t AsmAnalyzer::operator()(Identifier const& _identifier) m_errorReporter.typeError( 6041_error, nativeLocationOf(_identifier), - "Function " + _identifier.name.str() + " used without being called." + fmt::format("Function {} used without being called.", _identifier.name.str()) ); } })) { if (m_resolver) // We found a local reference, make sure there is no external reference. - m_resolver( + // Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value + std::ignore = m_resolver( _identifier, yul::IdentifierContext::NonExternal, m_currentScope->insideFunction() @@ -213,7 +223,7 @@ size_t AsmAnalyzer::operator()(Identifier const& _identifier) m_errorReporter.declarationError( 8198_error, nativeLocationOf(_identifier), - "Identifier \"" + _identifier.name.str() + "\" not found." + fmt::format("Identifier \"{}\" not found.", _identifier.name.str()) ); } @@ -229,11 +239,12 @@ void AsmAnalyzer::operator()(ExpressionStatement const& _statement) m_errorReporter.typeError( 3083_error, nativeLocationOf(_statement), - "Top-level expressions are not supposed to return values (this expression returns " + - std::to_string(numReturns) + - " value" + - (numReturns == 1 ? "" : "s") + - "). Use ``pop()`` or assign them." + fmt::format( + "Top-level expressions are not supposed to return values (this expression returns {} value{}). " + "Use ``pop()`` or assign them.", + numReturns, + numReturns == 1 ? "" : "s" + ) ); } @@ -249,9 +260,10 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) m_errorReporter.declarationError( 9005_error, nativeLocationOf(_assignment), - "Variable " + - _variableName.name.str() + - " occurs multiple times on the left-hand side of the assignment." + fmt::format( + "Variable {} occurs multiple times on the left-hand side of the assignment.", + _variableName.name.str() + ) ); size_t numRhsValues = std::visit(*this, *_assignment.value); @@ -260,13 +272,12 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) m_errorReporter.declarationError( 8678_error, nativeLocationOf(_assignment), - "Variable count for assignment to \"" + - joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) + - "\" does not match number of values (" + - std::to_string(numVariables) + - " vs. " + - std::to_string(numRhsValues) + - ")" + fmt::format( + "Variable count for assignment to \"{}\" does not match number of values ({} vs. {})", + joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })), + numVariables, + numRhsValues + ) ); for (size_t i = 0; i < numVariables; ++i) @@ -296,13 +307,12 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) m_errorReporter.declarationError( 3812_error, nativeLocationOf(_varDecl), - "Variable count mismatch for declaration of \"" + - joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) + - + "\": " + - std::to_string(numVariables) + - " variables and " + - std::to_string(numValues) + - " values." + fmt::format( + "Variable count mismatch for declaration of \"{}\": {} variables and {} values.", + joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })), + numVariables, + numValues + ) ); } @@ -314,7 +324,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) { - yulAssert(!_funDef.name.empty(), ""); + yulAssert(!_funDef.name.empty()); expectValidIdentifier(_funDef.name, nativeLocationOf(_funDef)); Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get(); yulAssert(virtualBlock, ""); @@ -352,77 +362,89 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) std::optional numReturns; std::vector> const* literalArguments = nullptr; - if (BuiltinFunction const* builtin = resolveBuiltinFunction(_funCall.functionName, m_dialect)) - { - if (builtin->name == "selfdestruct") - m_errorReporter.warning( - 1699_error, - nativeLocationOf(_funCall.functionName), - "\"selfdestruct\" has been deprecated. " - "Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and " - "data associated with an account and only transfers its Ether to the beneficiary, " - "unless executed in the same transaction in which the contract was created (see EIP-6780). " - "Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. " - "Future changes to the EVM might further reduce the functionality of the opcode." - ); - else if ( - m_evmVersion.supportsTransientStorage() && - builtin->name == "tstore" && - !m_errorReporter.hasError({2394}) - ) - m_errorReporter.warning( - 2394_error, - nativeLocationOf(_funCall.functionName), - "Transient storage as defined by EIP-1153 can break the composability of smart contracts: " - "Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, " - "your contract may unintentionally misbehave when invoked multiple times in a complex transaction. " - "To avoid this, be sure to clear all transient storage at the end of any call to your contract. " - "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." - ); + std::visit( + GenericVisitor { + [&](BuiltinName const& _builtinName) + { + BuiltinFunction const& builtin = m_dialect.builtin(_builtinName.handle); + if (builtin.name == "selfdestruct") + m_errorReporter.warning( + 1699_error, + nativeLocationOf(_builtinName), + "\"selfdestruct\" has been deprecated. " + "Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and " + "data associated with an account and only transfers its Ether to the beneficiary, " + "unless executed in the same transaction in which the contract was created (see EIP-6780). " + "Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. " + "Future changes to the EVM might further reduce the functionality of the opcode." + ); + else if ( + builtin.name == "tstore" && + !m_errorReporter.hasError({2394}) + ) + { + yulAssert(m_evmVersion.supportsTransientStorage(), "tstore is only a builtin on EVMs that support transient storage"); + m_errorReporter.warning( + 2394_error, + nativeLocationOf(_builtinName), + "Transient storage as defined by EIP-1153 can break the composability of smart contracts: " + "Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, " + "your contract may unintentionally misbehave when invoked multiple times in a complex transaction. " + "To avoid this, be sure to clear all transient storage at the end of any call to your contract. " + "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." + ); + } - numParameters = builtin->numParameters; - numReturns = builtin->numReturns; - if (!builtin->literalArguments.empty()) - literalArguments = &builtin->literalArguments; + numParameters = builtin.numParameters; + numReturns = builtin.numReturns; + if (!builtin.literalArguments.empty()) + literalArguments = &builtin.literalArguments; - validateInstructions(_funCall); - m_sideEffects += builtin->sideEffects; - } - else if (m_currentScope->lookup(YulName{resolveFunctionName(_funCall.functionName, m_dialect)}, GenericVisitor{ - [&](Scope::Variable const&) - { - m_errorReporter.typeError( - 4202_error, - nativeLocationOf(_funCall.functionName), - "Attempt to call variable instead of function." - ); + validateInstructions(_funCall); + m_sideEffects += builtin.sideEffects; + }, + [&](Identifier const& _identifier) + { + bool const identifierInCurrentScope = m_currentScope->lookup(_identifier.name, GenericVisitor{ + [&](Scope::Variable const&) + { + m_errorReporter.typeError( + 4202_error, + nativeLocationOf(_identifier), + "Attempt to call variable instead of function." + ); + }, + [&](Scope::Function const& _fun) + { + numParameters = _fun.numArguments; + numReturns = _fun.numReturns; + } + }); + if (identifierInCurrentScope) + { + if (m_resolver) + // We found a local reference, make sure there is no external reference. + // Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value + std::ignore = m_resolver( + _identifier, + yul::IdentifierContext::NonExternal, + m_currentScope->insideFunction() + ); + } + else + { + if (!validateInstructions(_funCall)) + m_errorReporter.declarationError( + 4619_error, + nativeLocationOf(_identifier), + fmt::format("Function \"{}\" not found.", _identifier.name.str()) + ); + yulAssert(!watcher.ok(), "Expected a reported error."); + } + } }, - [&](Scope::Function const& _fun) - { - numParameters = _fun.numArguments; - numReturns = _fun.numReturns; - } - })) - { - yulAssert(std::holds_alternative(_funCall.functionName)); - if (m_resolver) - // We found a local reference, make sure there is no external reference. - m_resolver( - std::get(_funCall.functionName), - yul::IdentifierContext::NonExternal, - m_currentScope->insideFunction() - ); - } - else - { - if (!validateInstructions(_funCall)) - m_errorReporter.declarationError( - 4619_error, - nativeLocationOf(_funCall.functionName), - fmt::format("Function \"{}\" not found.", resolveFunctionName(_funCall.functionName, m_dialect)) - ); - yulAssert(!watcher.ok(), "Expected a reported error."); - } + _funCall.functionName + ); if (numParameters && _funCall.arguments.size() != *numParameters) m_errorReporter.typeError( @@ -455,7 +477,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 5859_error, nativeLocationOf(arg), - "Function expects " + to_string(*literalArgumentKind) + " literal." + fmt::format("Function expects {} literal.", to_string(*literalArgumentKind)) ); else if (*literalArgumentKind == LiteralKind::String) { @@ -467,7 +489,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 3517_error, nativeLocationOf(arg), - "Unknown data object \"" + formatLiteral(argumentAsLiteral) + "\"." + fmt::format("Unknown data object \"{}\".", formatLiteral(argumentAsLiteral)) ); } else if (functionName.substr(0, "verbatim_"s.size()) == "verbatim_") @@ -499,14 +521,17 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 7575_error, nativeLocationOf(arg), - "Data name \"" + formattedLiteral + "\" cannot be used as an argument of eofcreate/returncontract. " + - "An object name is only acceptable." + fmt::format( + "Data name \"{}\" cannot be used as an argument of eofcreate/returncontract. " + "An object name is only acceptable.", + formattedLiteral + ) ); else m_errorReporter.typeError( 8970_error, nativeLocationOf(arg), - "Unknown object \"" + formattedLiteral + "\"." + fmt::format("Unknown object \"{}\".", formattedLiteral) ); } } @@ -579,9 +604,7 @@ void AsmAnalyzer::operator()(Switch const& _switch) m_errorReporter.declarationError( 6792_error, nativeLocationOf(_case), - "Duplicate case \"" + - formatLiteral(*_case.value) + - "\" defined." + fmt::format("Duplicate case \"{}\" defined.", formatLiteral(*_case.value)) ); } @@ -631,9 +654,10 @@ void AsmAnalyzer::expectExpression(Expression const& _expr) m_errorReporter.typeError( 3950_error, nativeLocationOf(_expr), - "Expected expression to evaluate to one value, but got " + - std::to_string(numValues) + - " values instead." + fmt::format( + "Expected expression to evaluate to one value, but got {} values instead.", + numValues + ) ); } @@ -645,7 +669,7 @@ void AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) void AsmAnalyzer::checkAssignment(Identifier const& _variable) { - yulAssert(!_variable.name.empty(), ""); + yulAssert(!_variable.name.empty()); auto watcher = m_errorReporter.errorWatcher(); bool hasVariable = false; bool found = false; @@ -653,7 +677,8 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable) { if (m_resolver) // We found a local reference, make sure there is no external reference. - m_resolver( + // Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value + std::ignore = m_resolver( _variable, yul::IdentifierContext::NonExternal, m_currentScope->insideFunction() @@ -665,7 +690,7 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable) m_errorReporter.declarationError( 1133_error, nativeLocationOf(_variable), - "Variable " + _variable.name.str() + " used before it was declared." + fmt::format("Variable {} used before it was declared.", _variable.name.str()) ); else hasVariable = true; @@ -698,26 +723,27 @@ Scope& AsmAnalyzer::scope(Block const* _block) void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation const& _location) { + std::string_view const label = _identifier.str(); // NOTE: the leading dot case is handled by the parser not allowing it. - if (boost::ends_with(_identifier.str(), ".")) + if (label.ends_with('.')) m_errorReporter.syntaxError( 3384_error, _location, - "\"" + _identifier.str() + "\" is not a valid identifier (ends with a dot)." + fmt::format("\"{}\" is not a valid identifier (ends with a dot).", label) ); - if (_identifier.str().find("..") != std::string::npos) + if (label.find("..") != std::string::npos) m_errorReporter.syntaxError( 7771_error, _location, - "\"" + _identifier.str() + "\" is not a valid identifier (contains consecutive dots)." + fmt::format("\"{}\" is not a valid identifier (contains consecutive dots).", label) ); - if (m_dialect.reservedIdentifier(_identifier.str())) + if (m_dialect.reservedIdentifier(label)) m_errorReporter.declarationError( 5017_error, _location, - "The identifier \"" + _identifier.str() + "\" is reserved and can not be used." + fmt::format("The identifier \"{}\" is reserved and can not be used.", label) ); } @@ -744,7 +770,7 @@ bool AsmAnalyzer::validateInstructions(std::string_view _instructionIdentifier, 7223_error, _location, fmt::format( - "Builtin function \"{}\" is only available in EOF.", + "Builtin function \"{function}\" is only available in EOF.", fmt::arg("function", _instructionIdentifier) ) ); @@ -844,7 +870,7 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio 4328_error, _location, fmt::format( - "The \"{}\" instruction is only available in EOF.", + "The \"{instruction}\" instruction is only available in EOF.", fmt::arg("instruction", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name)) ) ); @@ -899,7 +925,7 @@ bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall) ); } -void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation _astRootLocation) +void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation const& _astRootLocation) { if (m_eofVersion.has_value()) { diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index e8c02fbec132..51b8cde2ba1f 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -62,7 +62,7 @@ class AsmAnalyzer langutil::ErrorReporter& _errorReporter, Dialect const& _dialect, ExternalIdentifierAccess::Resolver _resolver = ExternalIdentifierAccess::Resolver(), - Object::Structure const _objectStructure = {} + Object::Structure _objectStructure = {} ): m_resolver(std::move(_resolver)), m_info(_analysisInfo), @@ -85,7 +85,12 @@ class AsmAnalyzer static AsmAnalysisInfo analyzeStrictAssertCorrect( Dialect const& _dialect, Block const& _astRoot, - Object::Structure const _objectStructure + Object::Structure _objectStructure + ); + static AsmAnalysisInfo analyzeStrictAssertCorrect( + Dialect const& _dialect, + AST const& _ast, + Object::Structure _objectStructure ); size_t operator()(Literal const& _literal); @@ -98,9 +103,9 @@ class AsmAnalyzer void operator()(If const& _if); void operator()(Switch const& _switch); void operator()(ForLoop const& _forLoop); - void operator()(Break const&) { } - void operator()(Continue const&) { } - void operator()(Leave const&) { } + void operator()(Break const&) const { } + void operator()(Continue const&) const { } + void operator()(Leave const&) const { } void operator()(Block const& _block); /// @returns the worst side effects encountered during analysis (including within defined functions). @@ -109,7 +114,7 @@ class AsmAnalyzer /// Visits the expression, expects that it evaluates to exactly one value. /// Reports errors otherwise. void expectExpression(Expression const& _expr); - void expectUnlimitedStringLiteral(Literal const& _literal); + static void expectUnlimitedStringLiteral(Literal const& _literal); /// Verifies that a variable to be assigned to exists and can be assigned to. void checkAssignment(Identifier const& _variable); @@ -121,7 +126,7 @@ class AsmAnalyzer bool validateInstructions(std::string_view _instrIdentifier, langutil::SourceLocation const& _location); bool validateInstructions(FunctionCall const& _functionCall); - void validateObjectStructure(langutil::SourceLocation _astRootLocation); + void validateObjectStructure(langutil::SourceLocation const& _astRootLocation); yul::ExternalIdentifierAccess::Resolver m_resolver; Scope* m_currentScope = nullptr; From b9cbf1e7db82b74c1c07801a05f663321889ce26 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 21 Mar 2025 09:17:09 +0100 Subject: [PATCH 019/121] AsmAnalysis: Improve wording of invalid argument for eofcreate/returncontract error --- libyul/AsmAnalysis.cpp | 2 +- .../yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 480373d13271..b36eb48b415e 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -523,7 +523,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) nativeLocationOf(arg), fmt::format( "Data name \"{}\" cannot be used as an argument of eofcreate/returncontract. " - "An object name is only acceptable.", + "Only an object name is acceptable.", formattedLiteral ) ); diff --git a/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul index 1e9fad7d0244..06bb487d62f8 100644 --- a/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul +++ b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul @@ -10,4 +10,4 @@ object "a" { // EVMVersion: >=shanghai // bytecodeFormat: >=EOFv1 // ---- -// TypeError 7575: (52-59): Data name "data1" cannot be used as an argument of eofcreate/returncontract. An object name is only acceptable. +// TypeError 7575: (52-59): Data name "data1" cannot be used as an argument of eofcreate/returncontract. Only an object name is acceptable. From d1cbd8dc3f0bd390669a99c8e036b8d6fd215b89 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:02:44 +0100 Subject: [PATCH 020/121] interpreter uses yul AST instead of separate block and dialect --- test/libyul/YulInterpreterTest.cpp | 3 +-- test/tools/yulInterpreter/Inspector.cpp | 15 +++++++-------- test/tools/yulInterpreter/Inspector.h | 3 +-- test/tools/yulInterpreter/Interpreter.cpp | 5 ++--- test/tools/yulInterpreter/Interpreter.h | 4 ++-- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index d97211b9761d..42e0e7c6f543 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -80,8 +80,7 @@ std::string YulInterpreterTest::interpret(std::shared_ptr const& _ { Interpreter::run( state, - *_object->dialect(), - _object->code()->root(), + *_object->code(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false ); diff --git a/test/tools/yulInterpreter/Inspector.cpp b/test/tools/yulInterpreter/Inspector.cpp index 7746483a367a..5fec7f1c58d4 100644 --- a/test/tools/yulInterpreter/Inspector.cpp +++ b/test/tools/yulInterpreter/Inspector.cpp @@ -31,9 +31,9 @@ using namespace solidity::yul::test; namespace { -void printVariable(YulString const& _name, u256 const& _value) +void printVariable(std::string_view const _name, u256 const& _value) { - std::cout << "\t" << _name.str() << " = " << _value.str(); + std::cout << "\t" << _name << " = " << _value.str(); if (_value != 0) std::cout << " (" << toCompactHexWithPrefix(_value) << ")"; @@ -46,17 +46,16 @@ void printVariable(YulString const& _name, u256 const& _value) void InspectedInterpreter::run( std::shared_ptr _inspector, InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTrace ) { Scope scope; - InspectedInterpreter{_inspector, _state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); + InspectedInterpreter{_inspector, _state, _ast.dialect(), scope, _disableExternalCalls, _disableMemoryTrace}(_ast.root()); } -Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std::map const& _variables) +Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std::map const& _variables) { if (m_stepMode == NodeAction::RunNode) { @@ -99,7 +98,7 @@ Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std else if (input == "variables" || input == "v") { for (auto &&[yulStr, val]: _variables) - printVariable(yulStr, val); + printVariable(yulStr.str(), val); std::cout << std::endl; } else if ( @@ -120,7 +119,7 @@ Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std for (auto &&[yulStr, val]: _variables) if (yulStr.str() == varname) { - printVariable(yulStr, val); + printVariable(varname, val); found = true; break; } diff --git a/test/tools/yulInterpreter/Inspector.h b/test/tools/yulInterpreter/Inspector.h index 903ebc1142ea..3ea669b438a9 100644 --- a/test/tools/yulInterpreter/Inspector.h +++ b/test/tools/yulInterpreter/Inspector.h @@ -103,8 +103,7 @@ class InspectedInterpreter: public Interpreter static void run( std::shared_ptr _inspector, InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTracing ); diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index 2709d1b468aa..05db9f581fa5 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -109,14 +109,13 @@ void InterpreterState::dumpTraceAndState(std::ostream& _out, bool _disableMemory void Interpreter::run( InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTrace ) { Scope scope; - Interpreter{_state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); + Interpreter{_state, _ast.dialect(), scope, _disableExternalCalls, _disableMemoryTrace}(_ast.root()); } void Interpreter::operator()(ExpressionStatement const& _expressionStatement) diff --git a/test/tools/yulInterpreter/Interpreter.h b/test/tools/yulInterpreter/Interpreter.h index 427a30d9ea08..3dd6a4238d97 100644 --- a/test/tools/yulInterpreter/Interpreter.h +++ b/test/tools/yulInterpreter/Interpreter.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include @@ -162,8 +163,7 @@ class Interpreter: public ASTWalker /// activated e.g., Redundant store eliminator, Equal store eliminator. static void run( InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTracing ); From 8859625fdeb9a19f538d596d380e0fae28ea108e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:02:55 +0100 Subject: [PATCH 021/121] yulrun on AST --- test/tools/yulrun.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index 36d48858620b..a5fa05d934ce 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -63,6 +63,9 @@ std::pair, std::shared_ptr> parse(st solidity::frontend::OptimiserSettings::none(), DebugInfoSelection::Default() ); + auto const* evmDialect = dynamic_cast(&stack.dialect()); + // TODO: Add EOF support + solUnimplementedAssert(evmDialect && !evmDialect->eofVersion(), "No EOF support for yulrun yet."); if (stack.parseAndAnalyze("--INPUT--", _source)) { yulAssert(!Error::hasErrorsWarningsOrInfos(stack.errors()), "Parsed successfully but had errors."); @@ -87,13 +90,10 @@ void interpret(std::string const& _source, bool _inspect, bool _disableExternalC state.maxTraceSize = 10000; try { - Dialect const& dialect(EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion{}, std::nullopt)); - if (_inspect) - InspectedInterpreter::run(std::make_shared(_source, state), state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); - + InspectedInterpreter::run(std::make_shared(_source, state), state, *ast, _disableExternalCalls, /*disableMemoryTracing=*/false); else - Interpreter::run(state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); + Interpreter::run(state, *ast, _disableExternalCalls, /*disableMemoryTracing=*/false); } catch (InterpreterTerminatedGeneric const&) { From dafe00677e1ccf04fb4853d74885cfe7288b25e7 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:56:53 +0100 Subject: [PATCH 022/121] ossfuzz uses yul AST instead of separate block and dialect --- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 6 ++---- test/tools/ossfuzz/yulFuzzerCommon.cpp | 5 ++--- test/tools/ossfuzz/yulFuzzerCommon.h | 3 +-- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 6 ++---- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index a4515b30957a..9abf269c869a 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -90,8 +90,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), + *stack.parserResult()->code(), /*disableMemoryTracing=*/true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) @@ -100,8 +99,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) stack.optimize(); termReason = yulFuzzerUtil::interpret( os2, - stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), + *stack.parserResult()->code(), /*disableMemoryTracing=*/true ); diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp index b95df8f2138c..c34f4351c5d4 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.cpp +++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp @@ -23,8 +23,7 @@ using namespace solidity::yul::test::yul_fuzzer; yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( std::ostream& _os, - yul::Block const& _astRoot, - Dialect const& _dialect, + AST const& _ast, bool _disableMemoryTracing, bool _outputStorageOnly, size_t _maxSteps, @@ -52,7 +51,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( TerminationReason reason = TerminationReason::None; try { - Interpreter::run(state, _dialect, _astRoot, true, _disableMemoryTracing); + Interpreter::run(state, _ast, true, _disableMemoryTracing); } catch (StepLimitReached const&) { diff --git a/test/tools/ossfuzz/yulFuzzerCommon.h b/test/tools/ossfuzz/yulFuzzerCommon.h index afcb0f2d3c9e..dcfd0f833775 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.h +++ b/test/tools/ossfuzz/yulFuzzerCommon.h @@ -40,8 +40,7 @@ struct yulFuzzerUtil /// eliminator. static TerminationReason interpret( std::ostream& _os, - yul::Block const& _astRoot, - Dialect const& _dialect, + AST const& _ast, bool _disableMemoryTracing = false, bool _outputStorageOnly = false, size_t _maxSteps = maxSteps, diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index d15043972693..4edfbf7ba4ee 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -90,8 +90,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), + *stack.parserResult()->code(), /*disableMemoryTracing=*/true ); @@ -106,8 +105,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // TODO: Add EOF support termReason = yulFuzzerUtil::interpret( os2, - *astRoot, - EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), + *optimizerTest.optimizedObject()->code(), true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) From 77878e5d4a56ea175d131a2338052ab4ac1e9ceb Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 14 Mar 2025 13:14:01 +0100 Subject: [PATCH 023/121] add repeats to external.sh --- test/benchmarks/external.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index b003f0ba18d2..7ad3279ae360 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -42,9 +42,10 @@ source "${repo_root}/scripts/common.sh" # shellcheck source=scripts/common_cmdline.sh source "${repo_root}/scripts/common_cmdline.sh" -(( $# <= 1 )) || fail "Too many arguments. Usage: external.sh []" +(( $# <= 2 )) || fail "Too many arguments. Usage: external.sh [] []" solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" +num_repeats="${2:-1}" command_available "$solc" --version command_available "$(type -P time)" --version @@ -65,10 +66,10 @@ function benchmark_project { > /dev/null \ 2> "../stderr-${project}-${pipeline}.log" || true - printf '| %-21s | %8s | %6d s | %9d MiB | %9d |\n' \ + printf '| %-21s | %8s | %6.2f s | %9d MiB | %9d |\n' \ "$project" \ "$pipeline" \ - "$(jq '(.user + .sys) | round' "$time_file")" \ + "$(jq '(.user + .sys) * 100 | round / 100' "$time_file")" \ "$(jq '.mem / 1024 | round' "$time_file")" \ "$(jq '.exit' "$time_file")" cd .. @@ -96,8 +97,12 @@ echo "| File | Pipeline | Time | Memory (peak) | Exit code echo "|-----------------------|----------|---------:|--------------:|----------:|" for project in "${benchmarks[@]}"; do - benchmark_project legacy "$project" - benchmark_project ir "$project" + for ((i=0; i Date: Tue, 25 Mar 2025 20:58:29 +0200 Subject: [PATCH 024/121] fix: Remove unnecessary Expression temporary in CHCSmtLib2Interface fix: Remove unnecessary Expression temporary in CHCSmtLib2Interface Update CHCSmtLib2Interface.cpp Update CHCSmtLib2Interface.cpp add repeats to external.sh --- libsmtutil/CHCSmtLib2Interface.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 6b0534296f29..04cbad1ad489 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -465,9 +465,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp smtSolverInteractionRequire(isAtom(nameSortPair[0]), "Invalid format of CHC model"); SortPointer varSort = scopedParser.toSort(nameSortPair[1]); scopedParser.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); - // FIXME: Why Expression here? - Expression arg = scopedParser.toSMTUtilExpression(nameSortPair[0]); - predicateArgs.push_back(arg); + predicateArgs.push_back(scopedParser.toSMTUtilExpression(nameSortPair[0])); } auto parsedInterpretation = scopedParser.toSMTUtilExpression(interpretation); @@ -479,6 +477,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp }); Expression predicate(asAtom(args[1]), predicateArgs, SortProvider::boolSort); + // FIXME: Why do we need to represent the predicate as Expression? definitions.push_back(predicate == parsedInterpretation); } return Expression::mkAnd(std::move(definitions)); From a4489211c9a872e81235d35433cdffe318755c77 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 28 Mar 2025 09:30:49 +0100 Subject: [PATCH 025/121] SMTChecker: Move helper function towards its only usage We don't need a separate file for a single, relatively small, helper function. --- libsolidity/CMakeLists.txt | 2 - libsolidity/formal/CHC.cpp | 54 +++++++++++++++++++- libsolidity/formal/Invariants.cpp | 85 ------------------------------- libsolidity/formal/Invariants.h | 37 -------------- 4 files changed, 53 insertions(+), 125 deletions(-) delete mode 100644 libsolidity/formal/Invariants.cpp delete mode 100644 libsolidity/formal/Invariants.h diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 5925a50ac480..f0289acac3a8 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -117,8 +117,6 @@ set(sources formal/EncodingContext.h formal/ExpressionFormatter.cpp formal/ExpressionFormatter.h - formal/Invariants.cpp - formal/Invariants.h formal/ModelChecker.cpp formal/ModelChecker.h formal/ModelCheckerSettings.cpp diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index bab340051f82..67878084f61b 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -19,8 +19,8 @@ #include #include +#include #include -#include #include #include #include @@ -2134,6 +2134,58 @@ void CHC::checkVerificationTargets() m_safeTargets[m_verificationTargets.at(id).errorNode].insert(m_verificationTargets.at(id)); } +namespace +{ +std::map> collectInvariants( + smtutil::Expression const& _proof, + std::set const& _predicates, + ModelCheckerInvariants const& _invariantsSetting +) +{ + std::set targets; + if (_invariantsSetting.has(InvariantType::Contract)) + targets.insert("interface_"); + if (_invariantsSetting.has(InvariantType::Reentrancy)) + targets.insert("nondet_interface_"); + + std::map> equalities; + // Collect equalities where one of the sides is a predicate we're interested in. + util::BreadthFirstSearch{{&_proof}}.run([&](auto&& _expr, auto&& _addChild) { + if (_expr->name == "=") + for (auto const& t: targets) + { + auto arg0 = _expr->arguments.at(0); + auto arg1 = _expr->arguments.at(1); + if (boost::algorithm::starts_with(arg0.name, t)) + equalities.insert({arg0.name, {arg0, std::move(arg1)}}); + else if (boost::algorithm::starts_with(arg1.name, t)) + equalities.insert({arg1.name, {arg1, std::move(arg0)}}); + } + for (auto const& arg: _expr->arguments) + _addChild(&arg); + }); + + std::map> invariants; + for (auto pred: _predicates) + { + auto predName = pred->functor().name; + if (!equalities.count(predName)) + continue; + + solAssert(pred->contextContract(), ""); + + auto const& [predExpr, invExpr] = equalities.at(predName); + + static std::set const ignore{"true", "false"}; + auto r = substitute(invExpr, pred->expressionSubstitution(predExpr)); + // No point in reporting true/false as invariants. + if (!ignore.count(r.name)) + invariants[pred].insert(toSolidityStr(r)); + } + return invariants; +} +} // namespace + void CHC::checkAndReportTarget( CHCVerificationTarget const& _target, std::vector const& _placeholders, diff --git a/libsolidity/formal/Invariants.cpp b/libsolidity/formal/Invariants.cpp deleted file mode 100644 index 017ab1e3aedb..000000000000 --- a/libsolidity/formal/Invariants.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include - -#include -#include - -#include - -#include - -using boost::algorithm::starts_with; -using namespace solidity; -using namespace solidity::smtutil; -using namespace solidity::frontend::smt; - -namespace solidity::frontend::smt -{ - -std::map> collectInvariants( - smtutil::Expression const& _proof, - std::set const& _predicates, - ModelCheckerInvariants const& _invariantsSetting -) -{ - std::set targets; - if (_invariantsSetting.has(InvariantType::Contract)) - targets.insert("interface_"); - if (_invariantsSetting.has(InvariantType::Reentrancy)) - targets.insert("nondet_interface_"); - - std::map> equalities; - // Collect equalities where one of the sides is a predicate we're interested in. - util::BreadthFirstSearch{{&_proof}}.run([&](auto&& _expr, auto&& _addChild) { - if (_expr->name == "=") - for (auto const& t: targets) - { - auto arg0 = _expr->arguments.at(0); - auto arg1 = _expr->arguments.at(1); - if (starts_with(arg0.name, t)) - equalities.insert({arg0.name, {arg0, std::move(arg1)}}); - else if (starts_with(arg1.name, t)) - equalities.insert({arg1.name, {arg1, std::move(arg0)}}); - } - for (auto const& arg: _expr->arguments) - _addChild(&arg); - }); - - std::map> invariants; - for (auto pred: _predicates) - { - auto predName = pred->functor().name; - if (!equalities.count(predName)) - continue; - - solAssert(pred->contextContract(), ""); - - auto const& [predExpr, invExpr] = equalities.at(predName); - - static std::set const ignore{"true", "false"}; - auto r = substitute(invExpr, pred->expressionSubstitution(predExpr)); - // No point in reporting true/false as invariants. - if (!ignore.count(r.name)) - invariants[pred].insert(toSolidityStr(r)); - } - return invariants; -} - -} diff --git a/libsolidity/formal/Invariants.h b/libsolidity/formal/Invariants.h deleted file mode 100644 index b6459fccd415..000000000000 --- a/libsolidity/formal/Invariants.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#pragma once - -#include -#include - -#include -#include -#include - -namespace solidity::frontend::smt -{ - -std::map> collectInvariants( - smtutil::Expression const& _proof, - std::set const& _predicates, - ModelCheckerInvariants const& _invariantsSettings -); - -} From 5ea8f2587447a09daa4089322dc06d1f323a16e7 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 19 Mar 2025 13:40:09 +0100 Subject: [PATCH 026/121] Add support for enum values in NatSpec --- Changelog.md | 1 + libsolidity/ast/AST.h | 14 ++++- libsolidity/ast/ASTJsonExporter.cpp | 1 + libsolidity/ast/ASTJsonImporter.cpp | 3 +- libsolidity/parsing/Parser.cpp | 3 +- .../ASTJSON/enum_value_natspec.json | 56 +++++++++++++++++++ .../ASTJSON/enum_value_natspec.sol | 11 ++++ .../ASTJSON/enum_value_natspec_parseOnly.json | 50 +++++++++++++++++ .../{enum_no_docs.sol => enum.sol} | 0 .../{docstring_enum.sol => enum_value.sol} | 10 ++-- 10 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 test/libsolidity/ASTJSON/enum_value_natspec.json create mode 100644 test/libsolidity/ASTJSON/enum_value_natspec.sol create mode 100644 test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json rename test/libsolidity/natspecJSON/{enum_no_docs.sol => enum.sol} (100%) rename test/libsolidity/natspecJSON/{docstring_enum.sol => enum_value.sol} (55%) diff --git a/Changelog.md b/Changelog.md index 7efefca02d6a..525ed2d9e58b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: +* NatSpec: Capture Natspec documentation of `enum` values in the AST. Bugfixes: diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 0121bef332df..9c7cbbded2cc 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -823,11 +823,19 @@ class EnumDefinition: public Declaration, public StructurallyDocumented, public /** * Declaration of an Enum Value */ -class EnumValue: public Declaration +class EnumValue: public Declaration, public StructurallyDocumented { public: - EnumValue(int64_t _id, SourceLocation const& _location, ASTPointer const& _name): - Declaration(_id, _location, _name, _location) {} + EnumValue( + int64_t _id, + SourceLocation const& _location, + ASTPointer const& _name, + ASTPointer _documentation + ): + Declaration(_id, _location, _name, _location), + StructurallyDocumented(std::move(_documentation)) + { + } void accept(ASTVisitor& _visitor) override; void accept(ASTConstVisitor& _visitor) const override; diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 42627b5f7f7c..4eaa558713a7 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -430,6 +430,7 @@ bool ASTJsonExporter::visit(EnumValue const& _node) setJsonNode(_node, "EnumValue", { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), + std::make_pair("documentation", toJson(_node.documentation().get())), }); return false; } diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index d6cd7f43896a..2d2b66fd8d08 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -489,7 +489,8 @@ ASTPointer ASTJsonImporter::createEnumValue(Json const& _node) { return createASTNode( _node, - memberAsASTString(_node, "name") + memberAsASTString(_node, "name"), + _node.contains("documentation") && !_node["documentation"].is_null() ? createDocumentation(member(_node, "documentation")) : nullptr ); } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 08a319b5b597..8889e65087fa 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -824,8 +824,9 @@ ASTPointer Parser::parseEnumValue() { RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); + ASTPointer documentation = parseStructuredDocumentation(); nodeFactory.markEndPosition(); - return nodeFactory.createNode(expectIdentifierToken()); + return nodeFactory.createNode(expectIdentifierToken(), documentation); } ASTPointer Parser::parseEnumDefinition() diff --git a/test/libsolidity/ASTJSON/enum_value_natspec.json b/test/libsolidity/ASTJSON/enum_value_natspec.json new file mode 100644 index 000000000000..e468bb987064 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_natspec.json @@ -0,0 +1,56 @@ +{ + "absolutePath": "a", + "exportedSymbols": { + "Color": [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": [ + { + "canonicalName": "Color", + "id": 6, + "members": [ + { + "id": 1, + "name": "Red", + "nameLocation": "17:3:1", + "nodeType": "EnumValue", + "src": "17:3:1" + }, + { + "documentation": { + "id": 2, + "nodeType": "StructuredDocumentation", + "src": "26:57:1", + "text": "@notice example of notice\n @dev example of dev" + }, + "id": 3, + "name": "Green", + "nameLocation": "88:5:1", + "nodeType": "EnumValue", + "src": "88:5:1" + }, + { + "documentation": { + "id": 4, + "nodeType": "StructuredDocumentation", + "src": "99:23:1", + "text": "@dev example of dev" + }, + "id": 5, + "name": "Blue", + "nameLocation": "127:4:1", + "nodeType": "EnumValue", + "src": "127:4:1" + } + ], + "name": "Color", + "nameLocation": "5:5:1", + "nodeType": "EnumDefinition", + "src": "0:164:1" + } + ], + "src": "0:165:1" +} diff --git a/test/libsolidity/ASTJSON/enum_value_natspec.sol b/test/libsolidity/ASTJSON/enum_value_natspec.sol new file mode 100644 index 000000000000..e5209d644831 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_natspec.sol @@ -0,0 +1,11 @@ +enum Color { + Red, + /// @notice example of notice + /// @dev example of dev + Green, + /// @dev example of dev + Blue + /// @dev beyond last value +} + +// ---- diff --git a/test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json b/test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json new file mode 100644 index 000000000000..ff3d7c756ed1 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json @@ -0,0 +1,50 @@ +{ + "absolutePath": "a", + "id": 7, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 6, + "members": [ + { + "id": 1, + "name": "Red", + "nameLocation": "17:3:1", + "nodeType": "EnumValue", + "src": "17:3:1" + }, + { + "documentation": { + "id": 2, + "nodeType": "StructuredDocumentation", + "src": "26:57:1", + "text": "@notice example of notice\n @dev example of dev" + }, + "id": 3, + "name": "Green", + "nameLocation": "88:5:1", + "nodeType": "EnumValue", + "src": "88:5:1" + }, + { + "documentation": { + "id": 4, + "nodeType": "StructuredDocumentation", + "src": "99:23:1", + "text": "@dev example of dev" + }, + "id": 5, + "name": "Blue", + "nameLocation": "127:4:1", + "nodeType": "EnumValue", + "src": "127:4:1" + } + ], + "name": "Color", + "nameLocation": "5:5:1", + "nodeType": "EnumDefinition", + "src": "0:164:1" + } + ], + "src": "0:165:1" +} diff --git a/test/libsolidity/natspecJSON/enum_no_docs.sol b/test/libsolidity/natspecJSON/enum.sol similarity index 100% rename from test/libsolidity/natspecJSON/enum_no_docs.sol rename to test/libsolidity/natspecJSON/enum.sol diff --git a/test/libsolidity/natspecJSON/docstring_enum.sol b/test/libsolidity/natspecJSON/enum_value.sol similarity index 55% rename from test/libsolidity/natspecJSON/docstring_enum.sol rename to test/libsolidity/natspecJSON/enum_value.sol index d5ace6b14192..ccb3233a51b4 100644 --- a/test/libsolidity/natspecJSON/docstring_enum.sol +++ b/test/libsolidity/natspecJSON/enum_value.sol @@ -1,11 +1,13 @@ contract C { - /// @title example of title - /// @author example of author - /// @notice example of notice - /// @dev example of dev enum Color { + /// @custom red color Red, + /// @title example of title + /// @author example of author + /// @notice example of notice + /// @dev example of dev Green + /// @notice beyond last value } } // ---- From c4b454ac53ad6409cee612ddaf38d467b50a6299 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 2 Apr 2025 13:16:18 +0200 Subject: [PATCH 027/121] Docs --- docs/natspec-format.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index 2f0d1d6b40d9..40da3e5e3529 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -37,7 +37,7 @@ Documentation Example ===================== Documentation is inserted above each ``contract``, ``interface``, ``library``, -``function``, and ``event`` using the Doxygen notation format. +``function``, ``enum``, ``enum`` value and ``event`` using the Doxygen notation format. A ``public`` state variable is equivalent to a ``function`` for the purposes of NatSpec. @@ -116,13 +116,13 @@ in the same way as if it were tagged with ``@notice``. =============== ====================================================================================== ============================= Tag Context =============== ====================================================================================== ============================= -``@title`` A title that should describe the contract/interface contract, library, interface, struct, enum -``@author`` The name of the author contract, library, interface, struct, enum -``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum, error -``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum, error -``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event, error -``@return`` Documents the return variables of a contract's function function, public state variable -``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, public state variable +``@title`` A title that should describe the contract/interface contract, library, interface, struct, enum, enum values +``@author`` The name of the author contract, library, interface, struct, enum, enum values +``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum, enum values error +``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum, enum values, error +``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event, enum values, error +``@return`` Documents the return variables of a contract's function function, enum, enum values, public state variable +``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, enum, enum values, public state variable ``@custom:...`` Custom tag, semantics is application-defined everywhere =============== ====================================================================================== ============================= From c6084281e3e7ff0b969235acab44eb409f93f273 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 28 Mar 2025 09:49:35 +0100 Subject: [PATCH 028/121] SMTChecker: Refactor processing invariants from the solver Instead of extracting invariants as a single expression containing all predicates and their definitions, we represent invariants as a map from predicate names to the corresponding definitions. Additionally, we need to remember formal arguments of the predicate so we can apply substitutions to the definitions properly. I believe the previous representation was an artifact of how Z3 returns CHC model through its API. The new representation is more fitting for models extracted from SMT-LIB. --- libsmtutil/CHCSmtLib2Interface.cpp | 27 +++++------ libsmtutil/CHCSmtLib2Interface.h | 4 +- libsmtutil/CHCSolverInterface.h | 12 ++++- libsolidity/formal/CHC.cpp | 50 +++++++------------- libsolidity/formal/Predicate.cpp | 30 ++++++------ libsolidity/formal/Predicate.h | 4 +- libsolidity/formal/Z3CHCSmtLib2Interface.cpp | 15 +++--- 7 files changed, 65 insertions(+), 77 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 04cbad1ad489..b81eeb4fe06b 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -102,21 +102,18 @@ CHCSolverInterface::QueryResult CHCSmtLib2Interface::query(Expression const& _bl // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. // So we have to flip the answer. if (boost::starts_with(response, "sat")) - { - auto maybeInvariants = invariantsFromSolverResponse(response); - return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; - } - else if (boost::starts_with(response, "unsat")) + return {CheckResult::UNSATISFIABLE, invariantsFromSolverResponse(response), {}}; + if (boost::starts_with(response, "unsat")) result = CheckResult::SATISFIABLE; else if (boost::starts_with(response, "unknown")) result = CheckResult::UNKNOWN; else result = CheckResult::ERROR; - return {result, Expression(true), {}}; + return {result, {}, {}}; } catch(smtutil::SMTSolverInteractionError const&) { - return {CheckResult::ERROR, Expression(true), {}}; + return {CheckResult::ERROR, {}, {}}; } } @@ -416,7 +413,7 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi } -std::optional CHCSmtLib2Interface::invariantsFromSolverResponse(std::string const& _response) const +CHCSmtLib2Interface::Invariants CHCSmtLib2Interface::invariantsFromSolverResponse(std::string const& _response) const { std::stringstream ss(_response); std::string answer; @@ -438,7 +435,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp smtSolverInteractionRequire(parser.isEOF(), "Error during parsing CHC model"); smtSolverInteractionRequire(!parsedOutput.empty(), "Error during parsing CHC model"); auto& commands = parsedOutput.size() == 1 ? asSubExpressions(parsedOutput[0]) : parsedOutput; - std::vector definitions; + Invariants definitions; for (auto& command: commands) { auto& args = asSubExpressions(command); @@ -456,7 +453,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp inlineLetExpressions(interpretation); ScopedParser scopedParser(m_context); auto const& formalArguments = asSubExpressions(args[2]); - std::vector predicateArgs; + std::vector predicateArguments; for (auto const& formalArgument: formalArguments) { smtSolverInteractionRequire(!isAtom(formalArgument), "Invalid format of CHC model"); @@ -465,7 +462,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp smtSolverInteractionRequire(isAtom(nameSortPair[0]), "Invalid format of CHC model"); SortPointer varSort = scopedParser.toSort(nameSortPair[1]); scopedParser.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); - predicateArgs.push_back(scopedParser.toSMTUtilExpression(nameSortPair[0])); + predicateArguments.push_back(asAtom(nameSortPair[0])); } auto parsedInterpretation = scopedParser.toSMTUtilExpression(interpretation); @@ -476,11 +473,11 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp return first.name < second.name; }); - Expression predicate(asAtom(args[1]), predicateArgs, SortProvider::boolSort); - // FIXME: Why do we need to represent the predicate as Expression? - definitions.push_back(predicate == parsedInterpretation); + std::string const& predicateName = asAtom(args[1]); + smtSolverInteractionRequire(!definitions.contains(predicateName), "Predicates must be unique"); + definitions.emplace(predicateName, InvariantInfo{parsedInterpretation, predicateArguments}); } - return Expression::mkAnd(std::move(definitions)); + return definitions; } namespace diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index 0f8fc061d3df..5b45f1638012 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -94,8 +94,8 @@ class CHCSmtLib2Interface: public CHCSolverInterface /// Communicates with the solver via the callback. Throws SMTSolverError on error. virtual std::string querySolver(std::string const& _input); - /// Translates CHC solver response with a model to our representation of invariants. Returns None on error. - std::optional invariantsFromSolverResponse(std::string const& _response) const; + /// Translates CHC solver response with a model to our representation of invariants. + Invariants invariantsFromSolverResponse(std::string const& _response) const; std::set collectVariableNames(Expression const& _expr) const; diff --git a/libsmtutil/CHCSolverInterface.h b/libsmtutil/CHCSolverInterface.h index 8feb18aa8245..641d54cfb440 100644 --- a/libsmtutil/CHCSolverInterface.h +++ b/libsmtutil/CHCSolverInterface.h @@ -25,6 +25,7 @@ #include #include +#include #include namespace solidity::smtutil @@ -49,10 +50,19 @@ class CHCSolverInterface : public SolverInterface std::map> edges; }; + struct InvariantInfo + { + /// Predicate definition as SMT expression + Expression expression; + /// Names of the formal arguments of the predicate definition + std::vector variableNames; + }; + /// Maps predicate to its definition as given by the solver and the formal arguments of the predicate + using Invariants = std::unordered_map; struct QueryResult { CheckResult answer; - Expression invariant; + Invariants invariants; CexGraph cex; }; /// Takes a function application _expr and checks for reachability. diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 67878084f61b..fea13fde2360 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -34,9 +34,8 @@ #include #include -#include - #include +#include #include #include #include @@ -1895,7 +1894,7 @@ CHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, la 2339_error, "CHC: Requested query:\n" + smtLibCode ); - return {.answer = CheckResult::UNKNOWN, .invariant = smtutil::Expression(true), .cex = {}}; + return {.answer = CheckResult::UNKNOWN, .invariants = {}, .cex = {}}; } auto result = m_interface->query(_query); switch (result.answer) @@ -2137,7 +2136,7 @@ void CHC::checkVerificationTargets() namespace { std::map> collectInvariants( - smtutil::Expression const& _proof, + CHCSmtLib2Interface::Invariants const& _invariants, std::set const& _predicates, ModelCheckerInvariants const& _invariantsSetting ) @@ -2148,38 +2147,23 @@ std::map> collectInvariants( if (_invariantsSetting.has(InvariantType::Reentrancy)) targets.insert("nondet_interface_"); - std::map> equalities; - // Collect equalities where one of the sides is a predicate we're interested in. - util::BreadthFirstSearch{{&_proof}}.run([&](auto&& _expr, auto&& _addChild) { - if (_expr->name == "=") - for (auto const& t: targets) - { - auto arg0 = _expr->arguments.at(0); - auto arg1 = _expr->arguments.at(1); - if (boost::algorithm::starts_with(arg0.name, t)) - equalities.insert({arg0.name, {arg0, std::move(arg1)}}); - else if (boost::algorithm::starts_with(arg1.name, t)) - equalities.insert({arg1.name, {arg1, std::move(arg0)}}); - } - for (auto const& arg: _expr->arguments) - _addChild(&arg); - }); - std::map> invariants; - for (auto pred: _predicates) + for (auto const* pred: _predicates) { - auto predName = pred->functor().name; - if (!equalities.count(predName)) + smtAssert(pred); + auto const& predName = pred->functor().name; + if (!_invariants.contains(predName)) + continue; + if (ranges::none_of(targets, [&](auto const& _target) { return predName.starts_with(_target); })) continue; - solAssert(pred->contextContract(), ""); + smtAssert(pred->contextContract()); - auto const& [predExpr, invExpr] = equalities.at(predName); + auto const& [definition, formalArguments] = _invariants.at(predName); - static std::set const ignore{"true", "false"}; - auto r = substitute(invExpr, pred->expressionSubstitution(predExpr)); + auto r = substitute(definition, pred->expressionSubstitution(formalArguments)); // No point in reporting true/false as invariants. - if (!ignore.count(r.name)) + if (r.name != "true" && r.name != "false") invariants[pred].insert(toSolidityStr(r)); } return invariants; @@ -2205,7 +2189,7 @@ void CHC::checkAndReportTarget( placeholder.constraints && placeholder.errorExpression == _target.errorId ); auto const& location = _target.errorNode->location(); - auto [result, invariant, model] = query(error(), location); + auto [result, invariants, model] = query(error(), location); if (result == CheckResult::UNSATISFIABLE) { m_safeTargets[_target.errorNode].insert(_target); @@ -2214,9 +2198,9 @@ void CHC::checkAndReportTarget( predicates.insert(pred); for (auto const* pred: m_nondetInterfaces | ranges::views::values) predicates.insert(pred); - std::map> invariants = collectInvariants(invariant, predicates, m_settings.invariants); - for (auto pred: invariants | ranges::views::keys) - m_invariants[pred] += std::move(invariants.at(pred)); + std::map> invariantStrings = collectInvariants(invariants, predicates, m_settings.invariants); + for (auto pred: invariantStrings | ranges::views::keys) + m_invariants[pred] += std::move(invariantStrings.at(pred)); } else if (result == CheckResult::SATISFIABLE) { diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 4b7ca8edb324..66d8c2405538 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -27,12 +27,10 @@ #include #include -#include #include #include -using boost::algorithm::starts_with; using namespace solidity; using namespace solidity::smtutil; using namespace solidity::frontend; @@ -434,15 +432,15 @@ std::pair>, std::vector Predicate::expressionSubstitution(smtutil::Expression const& _predExpr) const +std::map Predicate::expressionSubstitution(std::vector const& _predArgs) const { std::map subst; std::string predName = functor().name; - solAssert(contextContract(), ""); + smtAssert(contextContract()); auto const& stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*contextContract()); - auto nArgs = _predExpr.arguments.size(); + auto const nArgs = _predArgs.size(); // The signature of an interface predicate is // interface(this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, blockchainState, stateVariables). @@ -450,12 +448,13 @@ std::map Predicate::expressionSubstitution(smtutil::Ex // invariant over its state, for example `x <= 0`. if (isInterface()) { + smtAssert(nArgs > 0); size_t shift = txValuesIndex(); - solAssert(starts_with(predName, "interface"), ""); - subst[_predExpr.arguments.at(0).name] = "address(this)"; - solAssert(nArgs == stateVars.size() + shift, ""); + smtAssert(predName.starts_with("interface")); + subst[_predArgs.at(0)] = "address(this)"; + smtAssert(nArgs == stateVars.size() + shift); for (size_t i = nArgs - stateVars.size(); i < nArgs; ++i) - subst[_predExpr.arguments.at(i).name] = stateVars.at(i - shift)->name(); + subst[_predArgs.at(i)] = stateVars.at(i - shift)->name(); } // The signature of a nondet interface predicate is // nondet_interface(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, blockchainState, stateVariables, blockchainState', stateVariables'). @@ -466,14 +465,15 @@ std::map Predicate::expressionSubstitution(smtutil::Ex // `(x <= 0) => (x' <= 100)`. else if (isNondetInterface()) { - solAssert(starts_with(predName, "nondet_interface"), ""); - subst[_predExpr.arguments.at(0).name] = ""; - subst[_predExpr.arguments.at(1).name] = "address(this)"; - solAssert(nArgs == stateVars.size() * 2 + firstArgIndex(), ""); + smtAssert(nArgs > 1); + smtAssert(predName.starts_with("nondet_interface")); + subst[_predArgs.at(0)] = ""; + subst[_predArgs.at(1)] = "address(this)"; + smtAssert(nArgs == stateVars.size() * 2 + firstArgIndex()); for (size_t i = nArgs - stateVars.size(), s = 0; i < nArgs; ++i, ++s) - subst[_predExpr.arguments.at(i).name] = stateVars.at(s)->name() + "'"; + subst[_predArgs.at(i)] = stateVars.at(s)->name() + "'"; for (size_t i = nArgs - (stateVars.size() * 2 + 1), s = 0; i < nArgs - (stateVars.size() + 1); ++i, ++s) - subst[_predExpr.arguments.at(i).name] = stateVars.at(s)->name(); + subst[_predArgs.at(i)] = stateVars.at(s)->name(); } return subst; diff --git a/libsolidity/formal/Predicate.h b/libsolidity/formal/Predicate.h index f389ab822111..7e4ba0f00fe8 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -179,9 +179,9 @@ class Predicate /// @returns the values of the local variables used by this predicate. std::pair>, std::vector> localVariableValues(std::vector const& _args) const; - /// @returns a substitution map from the arguments of _predExpr + /// @returns a substitution map from the predicate arguments @p _predArgs /// to a Solidity-like expression. - std::map expressionSubstitution(smtutil::Expression const& _predExprs) const; + std::map expressionSubstitution(std::vector const& _predArgs) const; private: /// Recursively fills _array from _expr. diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp index 2ceecfcf9088..da6f14d963d3 100644 --- a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp @@ -90,26 +90,23 @@ CHCSolverInterface::QueryResult Z3CHCSmtLib2Interface::query(smtutil::Expression #endif setupSmtCallback(true); if (!boost::starts_with(response, "unsat")) - return {CheckResult::SATISFIABLE, Expression(true), {}}; - return {CheckResult::SATISFIABLE, Expression(true), graphFromZ3Answer(response)}; + return {CheckResult::SATISFIABLE, {}, {}}; + return {CheckResult::SATISFIABLE, {}, graphFromZ3Answer(response)}; } CheckResult result; if (boost::starts_with(response, "sat")) - { - auto maybeInvariants = invariantsFromSolverResponse(response); - return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; - } - else if (boost::starts_with(response, "unknown")) + return {CheckResult::UNSATISFIABLE, invariantsFromSolverResponse(response), {}}; + if (boost::starts_with(response, "unknown")) result = CheckResult::UNKNOWN; else result = CheckResult::ERROR; - return {result, Expression(true), {}}; + return {result, {}, {}}; } catch(smtutil::SMTSolverInteractionError const&) { - return {CheckResult::ERROR, Expression(true), {}}; + return {CheckResult::ERROR, {}, {}}; } } From dbd5521a697eae275afeb5d8a0b256670238f5b9 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 4 Apr 2025 07:50:21 +0200 Subject: [PATCH 029/121] remove install of obsolete jsoncpp --- .circleci/osx_install_dependencies.sh | 3 --- scripts/install_obsolete_jsoncpp_1_7_4.sh | 24 ----------------------- 2 files changed, 27 deletions(-) delete mode 100755 scripts/install_obsolete_jsoncpp_1_7_4.sh diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index e7a0b9ddfda2..6e0c859f9ace 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -59,9 +59,6 @@ then brew install openjdk@11 brew install unzip - # writing to /usr/local/lib need administrative privileges. - sudo ./scripts/install_obsolete_jsoncpp_1_7_4.sh - # boost boost_version="1.84.0" boost_package="boost_${boost_version//./_}.tar.bz2" diff --git a/scripts/install_obsolete_jsoncpp_1_7_4.sh b/scripts/install_obsolete_jsoncpp_1_7_4.sh deleted file mode 100755 index f9de0245d70b..000000000000 --- a/scripts/install_obsolete_jsoncpp_1_7_4.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -set -eu - -TEMPDIR=$(mktemp -d) -( - cd "$TEMPDIR" - jsoncpp_version="1.7.4" - jsoncpp_package="jsoncpp-${jsoncpp_version}.tar.gz" - jsoncpp_sha256=10dcd0677e80727e572a1e462193e51a5fde3e023b99e144b2ee1a469835f769 - wget -O "$jsoncpp_package" https://github.com/open-source-parsers/jsoncpp/archive/${jsoncpp_version}.tar.gz - if ! [ "$(sha256sum "$jsoncpp_package")" = "${jsoncpp_sha256} ${jsoncpp_package}" ] - then - >&2 echo "ERROR: Downloaded jsoncpp source package has wrong checksum." - exit 1 - fi - tar xvzf "$jsoncpp_package" - cd "jsoncpp-${jsoncpp_version}" - mkdir -p build - cd build - cmake -DCMAKE_OSX_ARCHITECTURES:STRING="x86_64;arm64" -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" .. - make - make install -) -rm -r "$TEMPDIR" From f323bd4de27b635dab1ba249832a1ec0b054cf4e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 4 Apr 2025 09:07:12 +0200 Subject: [PATCH 030/121] cmake: use boost include dirs and version in status message --- cmake/EthDependencies.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 87a5e1b5e17e..56d90bb478e3 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -49,8 +49,7 @@ if (NOT TARGET Boost::boost) # header only target add_library(Boost::boost INTERFACE IMPORTED) set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS}) endif() -get_property(LOCATION TARGET Boost::boost PROPERTY INTERFACE_INCLUDE_DIRECTORIES) -message(STATUS "Found Boost headers in ${LOCATION}") +message(STATUS "Found Boost ${Boost_VERSION} headers in ${Boost_INCLUDE_DIRS}") foreach (BOOST_COMPONENT IN LISTS BOOST_COMPONENTS) if (NOT TARGET Boost::${BOOST_COMPONENT}) From e6d56997aba55b2805a288b671d14651bd140270 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 4 Apr 2025 09:17:23 +0200 Subject: [PATCH 031/121] set CMP0167 to OLD behavior for boost versions < 1.70 --- cmake/EthDependencies.cmake | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 56d90bb478e3..f79140dd29d9 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -31,6 +31,10 @@ endif() set(BOOST_COMPONENTS "filesystem;unit_test_framework;program_options;system") +# CMake >= 3.30 should not use the vendored boost +if(POLICY CMP0167) + cmake_policy(SET CMP0167 NEW) +endif() if (WIN32) # Boost 1.77 fixes a bug that causes crashes on Windows for some relative paths in --allow-paths. # See https://github.com/boostorg/filesystem/issues/201 @@ -38,7 +42,16 @@ if (WIN32) else() # Boost 1.65 is the first to also provide boost::get for rvalue-references (#5787). # Boost 1.67 moved container_hash into is own module. - find_package(Boost 1.67.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + # Boost 1.70 comes with its own BoostConfig.cmake and is the new (non-deprecated) behavior + find_package(Boost 1.70.0 QUIET COMPONENTS ${BOOST_COMPONENTS}) + if (NOT ${Boost_FOUND}) + # If the boost version is < 1.70.0, there is no boost config delivered with it, revert to old behavior + # todo drop this once cmake minimum version >= 3.30 is reached + if(POLICY CMP0167) + cmake_policy(SET CMP0167 OLD) + endif() + find_package(Boost 1.67.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + endif() endif() # If cmake is older than boost and boost is older than 1.70, From 4c23d04b53cba7bfda8ddf19ead131e88529e003 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 7 Apr 2025 16:00:49 +0200 Subject: [PATCH 032/121] Disable pedantic compilation for CMake 4.0.0 and AppleClang 15.0 --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b39878f26d3..29bf2b0ca663 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,14 @@ endif() find_package(Threads) +if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + if (CMAKE_VERSION VERSION_EQUAL "4.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "15.0.0.15000040") + # for Apple clang 15 under cmake 4.0.0, disable pedantic warnings explicitly as it fails to treat boost properly as + # system library, warnings propagate + set(PEDANTIC OFF) + endif() +endif() + if(NOT PEDANTIC) message(WARNING "-- Pedantic build flags turned off. Warnings will not make compilation fail. This is NOT recommended in development builds.") endif() From 2cd97dc2b248edfac74241036cf7327d035bae57 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:34:38 +0200 Subject: [PATCH 033/121] Use pre-release version of sphinx-a4doc for python 3.13 --- docs/requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index b1b21a8691d3..e0c87915b40a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,7 +4,9 @@ sphinx_rtd_theme>=0.5.2 pygments-lexer-solidity>=0.7.0 -sphinx-a4doc>=1.6.0 +sphinx-a4doc>=1.6.0; python_version < '3.13' +# todo remove this once there is a version > 1.6.0 +sphinx-a4doc @ git+https://github.com/taminomara/sphinx-a4doc@f63d3b2; python_version >= '3.13' # Sphinx 2.1.0 is the oldest version that accepts a lexer class in add_lexer() sphinx>=2.1.0, <6.0 From 0a6cce58a0e3814db15844c53e05e384e00088fd Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:34:59 +0200 Subject: [PATCH 034/121] relax sphinx version range to [2.1, 9) --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index e0c87915b40a..8e058b6296b9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -9,4 +9,4 @@ sphinx-a4doc>=1.6.0; python_version < '3.13' sphinx-a4doc @ git+https://github.com/taminomara/sphinx-a4doc@f63d3b2; python_version >= '3.13' # Sphinx 2.1.0 is the oldest version that accepts a lexer class in add_lexer() -sphinx>=2.1.0, <6.0 +sphinx>=2.1.0, <9.0 From 971ac4c9ae79c4b7d5d76d23df1e1c9cd75b61ab Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:46:21 +0200 Subject: [PATCH 035/121] require rtd theme < 3.0.0 --- docs/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8e058b6296b9..f4c1aae61730 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,7 +1,8 @@ # Older versions of sphinx-rtd-theme do not work with never docutils but have a bug in the dependency # which could result in it being installed anyway and the style (especially bullet points) being broken. # See https://github.com/readthedocs/sphinx_rtd_theme/issues/1115 -sphinx_rtd_theme>=0.5.2 +# theme >=3.0.0 removes the display_version option in favor of version_selector and language_selector +sphinx_rtd_theme>=0.5.2, <3.0.0 pygments-lexer-solidity>=0.7.0 sphinx-a4doc>=1.6.0; python_version < '3.13' From 502ebaa8f879e8c5b5440a984030cf30f48c6f8a Mon Sep 17 00:00:00 2001 From: Michael Cho Date: Mon, 31 Mar 2025 16:06:00 -0400 Subject: [PATCH 036/121] Add support for upcoming Boost 1.88.0 Boost.Process will make v2 the default in Boost 1.88.0[^1] which breaks compilation of prior code. For a simple fix, this commit updates to use the newer paths for v1 until the code is updated to use v2 API. [^1]: https://github.com/boostorg/process/commit/2ccd97cd48c5468b0609a488b59253efaa381711 --- libsolidity/formal/ModelChecker.cpp | 6 ++++++ libsolidity/interface/SMTSolverCommand.cpp | 9 +++++++++ test/libyul/ControlFlowGraphTest.cpp | 8 ++++++++ test/libyul/SSAControlFlowGraphTest.cpp | 8 ++++++++ test/libyul/StackLayoutGeneratorTest.cpp | 8 ++++++++ 5 files changed, 39 insertions(+) diff --git a/libsolidity/formal/ModelChecker.cpp b/libsolidity/formal/ModelChecker.cpp index 04d96f06746c..2d52414127a6 100644 --- a/libsolidity/formal/ModelChecker.cpp +++ b/libsolidity/formal/ModelChecker.cpp @@ -18,7 +18,13 @@ #include +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#endif #include #include diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 66adfd0c5e17..e6e0ded6252d 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -20,7 +20,16 @@ #include #include +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#include +#endif namespace solidity::frontend { diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index c0ab37956e4c..594b2f6c96ee 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -29,7 +29,15 @@ #include #ifdef ISOLTEST +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#endif #endif using namespace solidity; diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index c23a2ca5faf9..d2acee7bcb85 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -28,7 +28,15 @@ #include #ifdef ISOLTEST +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#endif #endif using namespace solidity; diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index eb34eabb1776..0c85b1a7b968 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -33,7 +33,15 @@ #include #ifdef ISOLTEST +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#endif #endif using namespace solidity; From 334b7685525367fe8bbe8781ec260fef0ee44f7b Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 12 Mar 2025 12:28:40 +0100 Subject: [PATCH 037/121] Remove Z3 from ppa scripts and add ubunutu plucky. --- scripts/deps-ppa/static_z3.sh | 267 ---------------------------------- scripts/release_ppa.sh | 11 +- 2 files changed, 4 insertions(+), 274 deletions(-) delete mode 100755 scripts/deps-ppa/static_z3.sh diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh deleted file mode 100755 index 140c40c6abb3..000000000000 --- a/scripts/deps-ppa/static_z3.sh +++ /dev/null @@ -1,267 +0,0 @@ -#!/usr/bin/env bash -############################################################################## -## This is used to package .deb packages and upload them to the launchpad -## ppa servers for building. -## -## It will clone the Z3 git from github on the specified version tag, -## create a source archive and push it to the ubuntu ppa servers. -## -## This requires the following entries in /etc/dput.cf: -## -## [cpp-build-deps] -## fqdn = ppa.launchpad.net -## method = ftp -## incoming = ~ethereum/cpp-build-deps -## login = anonymous -## -## To interact with launchpad, you need to set the variables $LAUNCHPAD_EMAIL -## and $LAUNCHPAD_KEYID in the file .release_ppa_auth in the root directory of -## the project to your launchpad email and pgp keyid. -## This could for example look like this: -## -## LAUNCHPAD_EMAIL=your-launchpad-email@ethereum.org -## LAUNCHPAD_KEYID=123ABCFFFFFFFF -## -############################################################################## - -set -e - -packagename=z3-static -version="$1" - -REPO_ROOT="$(dirname "$0")/../.." - -# shellcheck source=/dev/null -source "${REPO_ROOT}/scripts/common.sh" - -[[ $version != "" ]] || fail "Usage: $0 " - -sourcePPAConfig - -# Sanity check -checkDputEntries "\[cpp-build-deps\]" - -DISTRIBUTIONS="jammy noble oracular" - -for distribution in $DISTRIBUTIONS -do -cd /tmp/ -rm -rf "$distribution" -mkdir "$distribution" -cd "$distribution" - -pparepo=cpp-build-deps -ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/${pparepo}/+files - -# Fetch source -git clone --branch "z3-${version}" https://github.com/Z3Prover/z3.git -cd z3 - -debversion="${version}" - -CMAKE_OPTIONS="-DZ3_BUILD_LIBZ3_SHARED=OFF -DCMAKE_BUILD_TYPE=Release" - -# gzip will create different tars all the time and we are not allowed -# to upload the same file twice with different contents, so we only -# create it once. -if [ ! -e "/tmp/${packagename}_${debversion}.orig.tar.gz" ] -then - tar --exclude .git -czf "/tmp/${packagename}_${debversion}.orig.tar.gz" . -fi -cp "/tmp/${packagename}_${debversion}.orig.tar.gz" ../ - -# Create debian package information - -mkdir debian -echo 9 > debian/compat -# TODO: the Z3 packages have different build dependencies -cat < debian/control -Source: z3-static -Section: science -Priority: extra -Maintainer: Daniel Kirchner -Build-Depends: debhelper (>= 9.0.0), - cmake, - g++ (>= 5.0), - git, - libgmp-dev, - dh-python, - python3 -Standards-Version: 3.9.6 -Homepage: https://github.com/Z3Prover/z3 -Vcs-Git: https://github.com/Z3Prover/z3.git -Vcs-Browser: https://github.com/Z3Prover/z3 - -Package: z3-static -Architecture: any -Breaks: z3 -Replaces: z3 -Depends: \${misc:Depends}, \${shlibs:Depends} -Description: theorem prover from Microsoft Research - Z3 is a state-of-the art theorem prover from Microsoft Research. It can be - used to check the satisfiability of logical formulas over one or more - theories. Z3 offers a compelling match for software analysis and verification - tools, since several common software constructs map directly into supported - theories. - . - The Z3 input format is an extension of the one defined by the SMT-LIB 2.0 - standard. - - -Package: libz3-static-dev -Section: libdevel -Architecture: any-amd64 -Breaks: libz3-dev -Replaces: libz3-dev -Multi-Arch: same -Depends: \${shlibs:Depends}, \${misc:Depends} -Description: theorem prover from Microsoft Research - development files (static library) - Z3 is a state-of-the art theorem prover from Microsoft Research. It can be - used to check the satisfiability of logical formulas over one or more - theories. Z3 offers a compelling match for software analysis and verification - tools, since several common software constructs map directly into supported - theories. - . - This package can be used to invoke Z3 via its C++ API. -EOF -cat < debian/rules -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. -# -# Modified to make a template file for a multi-binary package with separated -# build-arch and build-indep targets by Bill Allombert 2001 - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -# This has to be exported to make some magic below work. -export DH_OPTIONS - - -%: - dh \$@ --buildsystem=cmake - -override_dh_auto_test: - -override_dh_shlibdeps: - dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info - -override_dh_auto_configure: - dh_auto_configure -- ${CMAKE_OPTIONS} - -override_dh_auto_install: - dh_auto_install --destdir debian/tmp -EOF -cat < debian/libz3-static-dev.install -usr/include/* -usr/lib/*/libz3.a -usr/lib/*/cmake/z3/* -EOF -cat < debian/z3-static.install -usr/bin/z3 -EOF -cat < debian/copyright -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: z3 -Source: https://github.com/Z3Prover/z3 - -Files: * -Copyright: Microsoft Corporation -License: Expat - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - . - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - -Files: debian/* -Copyright: 2019 Ethereum -License: GPL-3.0+ -This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - On Debian systems, the complete text of the GNU General - Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". -EOF -cat < debian/changelog -z3-static (0.0.1-1ubuntu0) saucy; urgency=low - - * Initial release. - - -- Daniel Mon, 03 Jun 2019 14:50:20 +0000 -EOF -mkdir debian/source -echo "3.0 (quilt)" > debian/source/format -chmod +x debian/rules - -versionsuffix=1ubuntu0~${distribution} -EMAIL="$LAUNCHPAD_EMAIL" dch -v "1:${debversion}-${versionsuffix}" "build of ${version}" - -# build source package -# If packages is rejected because original source is already present, add -# -sd to remove it from the .changes file -# -d disables the build dependencies check -debuild -S -d -sa -us -uc - -# prepare .changes file for Launchpad -sed -i -e "s/UNRELEASED/${distribution}/" -e s/urgency=medium/urgency=low/ ../*.changes - -# check if ubuntu already has the source tarball -( -cd .. -orig="${packagename}_${debversion}.orig.tar.gz" -# shellcheck disable=SC2012 -orig_size=$(ls -l "$orig" | cut -d ' ' -f 5) -orig_sha1=$(sha1sum "$orig" | cut -d ' ' -f 1) -orig_sha256=$(sha256sum "$orig" | cut -d ' ' -f 1) -orig_md5=$(md5sum "$orig" | cut -d ' ' -f 1) - -if wget --quiet -O "$orig-tmp" "$ppafilesurl/$orig" -then - echo "[WARN] Original tarball found in Ubuntu archive, using it instead" - mv "${orig}-tmp" "$orig" - # shellcheck disable=SC2012 - new_size=$(ls -l ./*.orig.tar.gz | cut -d ' ' -f 5) - new_sha1=$(sha1sum "$orig" | cut -d ' ' -f 1) - new_sha256=$(sha256sum "$orig" | cut -d ' ' -f 1) - new_md5=$(md5sum "$orig" | cut -d ' ' -f 1) - sed -i -e "s,$orig_sha1,$new_sha1,g" -e "s,$orig_sha256,$new_sha256,g" -e "s,$orig_size,$new_size,g" -e "s,$orig_md5,$new_md5,g" ./*.dsc - sed -i -e "s,$orig_sha1,$new_sha1,g" -e "s,$orig_sha256,$new_sha256,g" -e "s,$orig_size,$new_size,g" -e "s,$orig_md5,$new_md5,g" ./*.changes -fi -) - -# sign the package -debsign --re-sign -k "${LAUNCHPAD_KEYID}" "../${packagename}_${debversion}-${versionsuffix}_source.changes" - -# upload -dput "${pparepo}" "../${packagename}_${debversion}-${versionsuffix}_source.changes" - -done diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index cf8df3d6c47d..2d0cbd180f56 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -68,7 +68,7 @@ packagename=solc # This needs to be a still active release static_build_distribution=noble -DISTRIBUTIONS="jammy noble oracular" +DISTRIBUTIONS="jammy noble oracular plucky" if is_release then @@ -103,17 +103,14 @@ else fi if [ "$distribution" = focal ] then - SMTDEPENDENCY="libz3-static-dev, - libcvc4-dev, + SMTDEPENDENCY="libcvc4-dev, " elif [ "$distribution" = disco ] then - SMTDEPENDENCY="libz3-static-dev, - libcvc4-dev, + SMTDEPENDENCY="libcvc4-dev, " else - SMTDEPENDENCY="libz3-static-dev, - " + SMTDEPENDENCY="" fi CMAKE_OPTIONS="" fi From 38810a3dc2d91aa51b2788a2df9170da421d34c2 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 8 Apr 2025 15:15:38 +0200 Subject: [PATCH 038/121] Adjust release checklist. --- ReleaseChecklist.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index f5e4ec7cae21..c9fcaba79fb7 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -85,10 +85,7 @@ At least a day before the release: ### PPA - [ ] Create `.release_ppa_auth` at the root of your local Solidity checkout and set `LAUNCHPAD_EMAIL` and `LAUNCHPAD_KEYID` to your key's email and key id. -- [ ] Double-check that the `DISTRIBUTIONS` list in `scripts/release_ppa.sh` and `scripts/deps-ppa/static_z3.sh` contains the most recent versions of Ubuntu. -- [ ] Make sure the [`~ethereum/cpp-build-deps` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains `libz3-static-dev` builds for all current versions of Ubuntu. - Note that it may be included in the `z3-static` multipackage (follow the `View package details` link to check). - If not present, run `scripts/deps-ppa/static_z3.sh` and wait for the builds to succeed before continuing. +- [ ] Double-check that the `DISTRIBUTIONS` list in `scripts/release_ppa.sh` contains the most recent versions of Ubuntu. - [ ] Run `scripts/release_ppa.sh v$VERSION` to create the PPA release. This will create a single package containing static binary for older Ubuntu versions in the [`~ethereum/ethereum-static` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) and separate packages with dynamically-linked binaries for recent versions (those listed in `DISTRIBUTIONS`) in the [`~ethereum/ethereum` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum). From fd2d543c6b7f6f134c6146dc8013814fd3e44c13 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 8 Apr 2025 15:21:33 +0200 Subject: [PATCH 039/121] Also drop libcvc4-dev and smtdependencies generally. --- scripts/release_ppa.sh | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 2d0cbd180f56..a8d89040f2dc 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -92,7 +92,6 @@ cd "$distribution" if [ "$distribution" = STATIC ] then pparepo=ethereum-static - SMTDEPENDENCY="" CMAKE_OPTIONS="-DSOLC_LINK_STATIC=On -DCMAKE_EXE_LINKER_FLAGS=-static" else if is_release @@ -101,17 +100,6 @@ else else pparepo=ethereum-dev fi - if [ "$distribution" = focal ] - then - SMTDEPENDENCY="libcvc4-dev, - " - elif [ "$distribution" = disco ] - then - SMTDEPENDENCY="libcvc4-dev, - " - else - SMTDEPENDENCY="" - fi CMAKE_OPTIONS="" fi ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/${pparepo}/+files @@ -153,7 +141,7 @@ Source: solc Section: science Priority: extra Maintainer: Christian (Buildserver key) -Build-Depends: ${SMTDEPENDENCY}debhelper (>= 9.0.0), +Build-Depends: debhelper (>= 9.0.0), cmake, g++ (>= 5.0), git, From e13c612202823d158e845df4435e405fd1576dea Mon Sep 17 00:00:00 2001 From: Henry Chu Date: Fri, 4 Apr 2025 16:28:43 +0800 Subject: [PATCH 040/121] Language Server: Fix hover crashes on invalid parameters When `textDocument/hover` gets an out-of-range request --- libsolidity/lsp/DocumentHoverHandler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libsolidity/lsp/DocumentHoverHandler.cpp b/libsolidity/lsp/DocumentHoverHandler.cpp index e5991b765a66..a4f3de25c014 100644 --- a/libsolidity/lsp/DocumentHoverHandler.cpp +++ b/libsolidity/lsp/DocumentHoverHandler.cpp @@ -59,6 +59,11 @@ void DocumentHoverHandler::operator()(MessageID _id, Json const& _args) { auto const [sourceUnitName, lineColumn] = HandlerBase(*this).extractSourceUnitNameAndLineColumn(_args); auto const [sourceNode, sourceOffset] = m_server.astNodeAndOffsetAtSourceLocation(sourceUnitName, lineColumn); + if (!sourceNode) + { + client().reply(_id, Json()); + return; + } MarkdownBuilder markdown; auto rangeToHighlight = toRange(sourceNode->location()); From 1cd7045cd2cf77a813b8b3baecfcfc5eb5b6af25 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 14 Apr 2025 08:52:53 +0200 Subject: [PATCH 041/121] Remove disable pedantic mode switch for osx cmake 4.0.0 and clang 15.0.0 --- CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29bf2b0ca663..5b39878f26d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,14 +70,6 @@ endif() find_package(Threads) -if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - if (CMAKE_VERSION VERSION_EQUAL "4.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "15.0.0.15000040") - # for Apple clang 15 under cmake 4.0.0, disable pedantic warnings explicitly as it fails to treat boost properly as - # system library, warnings propagate - set(PEDANTIC OFF) - endif() -endif() - if(NOT PEDANTIC) message(WARNING "-- Pedantic build flags turned off. Warnings will not make compilation fail. This is NOT recommended in development builds.") endif() From 09715e6d13f3922b96d671cddf463aea6523ad3e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 14 Apr 2025 09:18:54 +0200 Subject: [PATCH 042/121] osx ci: Install Boost to /opt/boost instead of /usr/local --- .circleci/config.yml | 10 ++++++++-- .circleci/osx_install_dependencies.sh | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d26ef3bd41a6..09b1281c5630 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -385,7 +385,7 @@ commands: name: Installing dependencies / Restoring dependency cache command: | if [[ -f ~/osx-dependencies-cached ]]; then - echo "Dependency flag exists. Removing /usr/local/ and /opt/homebrew/. These directories will be restored from cache." + echo "Dependency flag exists. Removing /usr/local/, /opt/homebrew/, and /opt/boost. These directories will be restored from cache." # CircleCI is providing the circleci cli tools via some kind of symlink magic. # So we just save the original symlinks and restore them later. @@ -405,6 +405,10 @@ commands: sudo mkdir -p /usr/local/bin sudo chmod 777 /usr/{local,local/bin} + sudo rm -rf /opt/boost + sudo mkdir -p /opt/boost + sudo chmod 777 /opt/boost + mv /tmp/circleci "${circleci_binary_path}" mv /tmp/circleci-agent "${circleci_agent_binary_path}" fi @@ -425,6 +429,7 @@ commands: # Homebrew is installed in /usr/local on intel macs, but in /opt/homebrew on apple silicon. - /usr/local - /opt/homebrew + - /opt/boost - save_cache: key: osx-dependencies-cached-{{ arch }}-{{ checksum ".circleci/osx_install_dependencies.sh" }} paths: @@ -1159,7 +1164,8 @@ jobs: environment: <<: *base_osx_env CMAKE_BUILD_TYPE: Release - CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64 + # boost root configured to the prefix used in `osx_install_dependencies.sh` + CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64 -DBoost_ROOT=/opt/boost steps: - checkout - install_dependencies_osx diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 6e0c859f9ace..367e8cbb40cb 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -69,7 +69,8 @@ then cd "$boost_dir" ./bootstrap.sh --with-toolset=clang --with-libraries=thread,system,filesystem,program_options,serialization,test # the default number of jobs that b2 is taking, is the number of detected available CPU threads. - sudo ./b2 -a address-model=64 architecture=arm+x86 install + # install boost to /opt/boost, to use it in CMake, specify Boost_ROOT + sudo ./b2 -a address-model=64 architecture=arm+x86 --prefix=/opt/boost install cd .. sudo rm -rf "$boost_dir" From f1c3a2d6eb2e071d5b09a0a472fd5871e342f83f Mon Sep 17 00:00:00 2001 From: closeobserve Date: Sun, 13 Apr 2025 19:13:59 +0800 Subject: [PATCH 043/121] chore: remove redundant word in comment Signed-off-by: closeobserve --- libsolidity/codegen/YulUtilFunctions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 5ea99d603083..c28ba855c816 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -560,7 +560,7 @@ class YulUtilFunctions /// Signature: (address) -> mpos std::string externalCodeFunction(); - /// @return the name of a function that that checks if two external functions pointers are equal or not + /// @return the name of a function that checks if two external functions pointers are equal or not std::string externalFunctionPointersEqualFunction(); private: From 1706158dbb4e2525695c8cef023b87b37052af4c Mon Sep 17 00:00:00 2001 From: futreall <86553580+futreall@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:41:27 +0200 Subject: [PATCH 044/121] Update premium.sol --- test/compilationTests/corion/premium.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compilationTests/corion/premium.sol b/test/compilationTests/corion/premium.sol index 646ab00e1594..2702aa5bb815 100644 --- a/test/compilationTests/corion/premium.sol +++ b/test/compilationTests/corion/premium.sol @@ -229,7 +229,7 @@ contract premium is module, safeMath { function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) { /* Launch a transaction where we transfer from a given address to another one. - After thetransaction the approvedCorionPremiumToken function of the receiver’s address is going to be called with the given data. + After the transaction the approvedCorionPremiumToken function of the receiver’s address is going to be called with the given data. @to For who? @amount Amount From a1be4f313dd4120b5cb5994fe93f03c76e1de9ba Mon Sep 17 00:00:00 2001 From: futreall <86553580+futreall@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:41:58 +0200 Subject: [PATCH 045/121] Update publisher.sol --- test/compilationTests/corion/publisher.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/compilationTests/corion/publisher.sol b/test/compilationTests/corion/publisher.sol index 311e8d92e725..27d90a27e89b 100644 --- a/test/compilationTests/corion/publisher.sol +++ b/test/compilationTests/corion/publisher.sol @@ -205,8 +205,8 @@ contract publisher is announcementTypes, module, safeMath { If announcement is opposable, anyone owning a token can oppose it Opposition is automatically with the total amount of tokens If the quantity of his tokens changes, the purport of his opposition changes automatically - The prime time is the windup of the announcement, because this is the moment when the number of tokens in opposition are counted. - One address is entitled to be in oppositon only once. An opposition cannot be withdrawn. + The prime time is the windup of the announcement, because this is the moment when the number of tokens in opposition are counted. + One address is entitled to be in opposition only once. An opposition cannot be withdrawn. Running announcements can be opposed only. @id Announcement identification From 513535a75849bf18c44e24f31e56aad4d1b4b94f Mon Sep 17 00:00:00 2001 From: matta Date: Fri, 8 Mar 2024 17:17:06 -0300 Subject: [PATCH 046/121] Adding clarity on extcalls with precompiled contracts. --- docs/control-structures.rst | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 1d21a6e2668e..8a815e10ef0f 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -111,22 +111,35 @@ otherwise, the ``value`` option would not be available. the ``value`` and ``gas`` settings are lost, only ``feed.info{value: 10, gas: 800}()`` performs the function call. -Due to the fact that the EVM considers a call to a non-existing contract to -always succeed, Solidity uses the ``extcodesize`` opcode to check that -the contract that is about to be called actually exists (it contains code) -and causes an exception if it does not. This check is skipped if the return -data will be decoded after the call and thus the ABI decoder will catch the -case of a non-existing contract. +.. warning:: + Due to the fact that the EVM considers a call to a non-existing contract to + always succeed, Solidity uses the ``extcodesize`` opcode to check that + the contract that is about to be called actually exists (it contains code) + and causes an exception if it does not. This check is skipped if the return + data will be decoded after the call and thus the ABI decoder will catch the + case of a non-existing contract. -Note that this check is not performed in case of :ref:`low-level calls ` which -operate on addresses rather than contract instances. + This check is not performed in case of :ref:`low-level calls ` which + operate on addresses rather than contract instances. -.. note:: +.. warning:: Be careful when using high-level calls to :ref:`precompiled contracts `, since the compiler considers them non-existing according to the above logic even though they execute code and can return data. +.. note:: + Since the version 0.8.10, the compiler does not check ``extcodesize`` on + high-level external calls if return data is expected, because an empty code + will be unable to return data, and the ABI decoder will revert. + As a consequence, this allows high-level external calls to precompiled + contracts, since they can return data despite having no code + associated with their addresses. + + Read about :ref:`precompiled contracts ` and + :ref:`low-level calls ` + for more information. + Function calls also cause exceptions if the called contract itself throws an exception or goes out of gas. @@ -901,4 +914,4 @@ in scope in the block that follows. out-of-gas situation and not a deliberate error condition: The caller always retains at least 1/64th of the gas in a call and thus even if the called contract goes out of gas, the caller still - has some gas left. + has some gas left. \ No newline at end of file From 8b85d14f7d1e3cbb476434dec2af60c456af7fe4 Mon Sep 17 00:00:00 2001 From: Bilog WEB3 <155262265+Bilogweb3@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:50:31 +0100 Subject: [PATCH 047/121] Update custom.css --- docs/_static/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index d2c9c86e7b2e..bdfb5ce0bce5 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -93,7 +93,7 @@ h1 { } section:first-of-type h1:first-of-type { - font-family: 'Overpass mono', monospace; + font-family: 'Overpass Mono', monospace; font-size: 48px; margin-top: 3rem; margin-bottom: 5rem; From eda68d51fdefd92186bb4390d8b2eaaae2bf7c93 Mon Sep 17 00:00:00 2001 From: PixelPilot <161360836+PixelPil0t1@users.noreply.github.com> Date: Tue, 11 Mar 2025 15:15:18 +0100 Subject: [PATCH 048/121] Update events.rst --- docs/contracts/events.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contracts/events.rst b/docs/contracts/events.rst index 8c73c31603ae..c83970099a65 100644 --- a/docs/contracts/events.rst +++ b/docs/contracts/events.rst @@ -15,7 +15,7 @@ arguments to be stored in the transaction's log - a special data structure in the blockchain. These logs are associated with the address of the contract that emitted them, are incorporated into the blockchain, and stay there as long as a block is accessible (forever as of now, but this might -change in the future). The Log and its event data is not accessible from within +change in the future). The Log and its event data are not accessible from within contracts (not even from the contract that created them). It is possible to request a Merkle proof for logs, so if From feed69b5cac1e9519b881878b6595a2ee893835f Mon Sep 17 00:00:00 2001 From: argentpapa Date: Fri, 28 Feb 2025 01:17:33 +0800 Subject: [PATCH 049/121] Update calling_nonexisting_contract.sol --- .../functionCall/eof/calling_nonexisting_contract.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol index 10b39634d5de..a1a53e09d89a 100644 --- a/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol +++ b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol @@ -8,7 +8,7 @@ contract C { function f() public returns (uint256) { // This call throws on legacy bytecode because of calling nonexisting contract. Legacy checks that there is - // a non-empty code under under an address. EOF doesn't do it because non-observability assumption + // a non-empty code under an address. EOF doesn't do it because non-observability assumption d.g(); return 7; } From ba3fd65cfbc2450d538229febf87ea3863230a67 Mon Sep 17 00:00:00 2001 From: Voronor <129545215+voronor@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:23:39 +0100 Subject: [PATCH 050/121] docs: Fix grammar in workflow trigger condition --- scripts/docker/buildpack-deps/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker/buildpack-deps/README.md b/scripts/docker/buildpack-deps/README.md index 9cfcafd4bf27..6149165c8941 100644 --- a/scripts/docker/buildpack-deps/README.md +++ b/scripts/docker/buildpack-deps/README.md @@ -6,7 +6,7 @@ The `buildpack-deps` docker images are used to compile and test solidity within The creation of the images is triggered by a single workflow, defined in `.github/workflows/buildpack-deps.yml`. For each resulting `buildpack-deps` docker image a strategy is defined in the workflow file - the image variant. -The workflow gets triggered, if any Dockerfile defined in `scripts/docker/buildpack-deps/Dockerfile.*` were changed +The workflow gets triggered, if any Dockerfile defined in `scripts/docker/buildpack-deps/Dockerfile.*` was changed within the PR. ### Versioning From ab77b34e67ae6327f80bdd5098889243b3a86d66 Mon Sep 17 00:00:00 2001 From: emmmm <155267286+eeemmmmmm@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:43:24 +0100 Subject: [PATCH 051/121] Update ControlFlowGraphBuilder.h --- libyul/backends/evm/ControlFlowGraphBuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index 1d0227a56b71..4a2aae98c26f 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -33,7 +33,7 @@ class ControlFlowGraphBuilder ControlFlowGraphBuilder& operator=(ControlFlowGraphBuilder const&) = delete; static std::unique_ptr build(AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block); - StackSlot operator()(Expression const& _literal); + StackSlot operator()(Expression const& _expression); StackSlot operator()(Literal const& _literal); StackSlot operator()(Identifier const& _identifier); StackSlot operator()(FunctionCall const&); From 10b21b89a6c2c8a00ea27706497607d28bb4cf19 Mon Sep 17 00:00:00 2001 From: "ferranmesas@gmx.es" Date: Fri, 28 Feb 2025 22:52:40 +0100 Subject: [PATCH 052/121] Replace temporary std::string with std::string_view in _yulname literal to avoid unnecessary allocations --- libyul/YulString.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/YulString.h b/libyul/YulString.h index d6c13f0d3751..329825a4465b 100644 --- a/libyul/YulString.h +++ b/libyul/YulString.h @@ -165,7 +165,7 @@ class YulString inline YulString operator "" _yulname(char const* _string, std::size_t _size) { - return YulString(std::string(_string, _size)); + return YulString(std::string_view(_string, _size)); } } From 771d8052df8947f781d126fea349734344941a3c Mon Sep 17 00:00:00 2001 From: NeoByteX <160131789+NeoByteXx@users.noreply.github.com> Date: Sat, 22 Feb 2025 08:33:10 +0100 Subject: [PATCH 053/121] Fix typo in test script comments --- test/externalTests/brink.sh | 2 +- test/externalTests/elementfi.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/externalTests/brink.sh b/test/externalTests/brink.sh index 02e5fe971c65..e541481b43ae 100755 --- a/test/externalTests/brink.sh +++ b/test/externalTests/brink.sh @@ -61,7 +61,7 @@ function brink_test setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$ref" "$DIR" - # TODO: Remove this when Brink merges https://github.com/brinktrade/brink-core/pull/52 + # TODO: Remove this once Brink merges PR #52 (https://github.com/brinktrade/brink-core/pull/52). sed -i "s|\(function isValidSignature(bytes \)calldata\( _data, bytes \)calldata\( _signature)\)|\1memory\2memory\3|g" src/Test/MockEIP1271Validator.sol neutralize_package_lock diff --git a/test/externalTests/elementfi.sh b/test/externalTests/elementfi.sh index f34a169e9512..aa73ea768740 100755 --- a/test/externalTests/elementfi.sh +++ b/test/externalTests/elementfi.sh @@ -93,8 +93,8 @@ function elementfi_test sed -i 's|it(\("should prevent withdrawal of Principal Tokens and Interest Tokens before the tranche expires "\)|it.skip(\1|g' test/trancheTest.ts sed -i 's|it(\("should prevent withdrawal of more Principal Tokens and Interest Tokens than the user has"\)|it.skip(\1|g' test/trancheTest.ts - # This test file is very flaky. There's one particular cases that fails randomly (see - # https://github.com/element-fi/elf-contracts/issues/240) but some others also depends on an external + # This test file is very flaky. There's one particular case that fails randomly (see + # https://github.com/element-fi/elf-contracts/issues/240) but some others also depend on an external # service which makes tests time out when that service is down. # "ProviderError: Too Many Requests error received from eth-mainnet.alchemyapi.io" rm test/mockERC20YearnVaultTest.ts From d22a07012e03cd3a942235aa166f00f0c000dcdb Mon Sep 17 00:00:00 2001 From: Skylar Ray <137945430+sky-coderay@users.noreply.github.com> Date: Fri, 14 Mar 2025 10:08:33 +0200 Subject: [PATCH 054/121] fix minor issues Update DataFlowAnalyzer.cpp Update CommonSubexpressionEliminator.cpp /*( -deleted ( --- libyul/CompilabilityChecker.cpp | 2 +- libyul/optimiser/CommonSubexpressionEliminator.cpp | 2 +- libyul/optimiser/DataFlowAnalyzer.cpp | 2 +- libyul/optimiser/Metrics.cpp | 2 +- libyul/optimiser/Rematerialiser.cpp | 2 +- libyul/optimiser/StackCompressor.cpp | 2 +- libyul/optimiser/SyntacticalEquality.cpp | 2 +- libyul/optimiser/UnusedPruner.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index cc46ecb77000..2df14f211939 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index 87a14d259070..1a6f3911a1bb 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 2407781354d0..1aecd6bd4a91 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index 04bfe9a7a06d..5c3a624269d5 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/Rematerialiser.cpp b/libyul/optimiser/Rematerialiser.cpp index bfcd9d8f630f..1d3535fdae82 100644 --- a/libyul/optimiser/Rematerialiser.cpp +++ b/libyul/optimiser/Rematerialiser.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 97d2c054700d..b0be60d63442 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp index e233b57e9e2d..a032e912be63 100644 --- a/libyul/optimiser/SyntacticalEquality.cpp +++ b/libyul/optimiser/SyntacticalEquality.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index 5d50e4599bfd..2f982b164093 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify From 02d2c9af23c830667ccbce4e581357a163615dea Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 9 Apr 2025 13:54:18 +0200 Subject: [PATCH 055/121] change into test dir for cmdline tests --- test/cmdlineTests.sh | 45 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index f68ed53dc066..b3327ea988c8 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -225,7 +225,7 @@ EOF if jq 'has("ethdebug")' "$stdout_path" --exit-status > /dev/null; then local temporary_file temporary_file=$(mktemp -t cmdline-ethdebug-XXXXXX.tmp) - if [[ -e ${tdir}/strip-ethdebug ]]; then + if [[ -e strip-ethdebug ]]; then jq --indent 4 ' (. | .. | objects | select(has("ethdebug"))) |= (.ethdebug = "") ' "$stdout_path" > "$temporary_file" @@ -350,9 +350,11 @@ test_solc_behaviour "${0}" "ctx:=/some/remapping/target" "" "" 1 "" "Error: Inva printTask "Running general commandline tests..." ( - cd "$REPO_ROOT"/test/cmdlineTests/ for tdir in "${selected_tests[@]}" do + # go back to the test root dir + cd "$REPO_ROOT"/test/cmdlineTests/ + if ! [[ -d $tdir ]] then fail "Test directory not found: $tdir" @@ -377,10 +379,13 @@ printTask "Running general commandline tests..." fi fi - scriptFiles="$(ls -1 "${tdir}/test."* 2> /dev/null || true)" + # jump into test dir + cd "${tdir}" + + scriptFiles="$(ls -1 "test."* 2> /dev/null || true)" scriptCount="$(echo "${scriptFiles}" | wc -w)" - inputFiles="$(ls -1 "${tdir}/input."* 2> /dev/null || true)" + inputFiles="$(ls -1 "input."* 2> /dev/null || true)" inputCount="$(echo "${inputFiles}" | wc -w)" (( inputCount <= 1 )) || fail "Ambiguous input. Found input files in multiple formats:"$'\n'"${inputFiles}" (( scriptCount <= 1 )) || fail "Ambiguous input. Found script files in multiple formats:"$'\n'"${scriptFiles}" @@ -388,7 +393,7 @@ printTask "Running general commandline tests..." if (( scriptCount == 1 )) then - if ! "$scriptFiles" + if ! "./$scriptFiles" then fail "Test script ${scriptFiles} failed." fi @@ -399,38 +404,38 @@ printTask "Running general commandline tests..." # Use printf to get rid of the trailing newline inputFile=$(printf "%s" "${inputFiles}") - if [ "${inputFile}" = "${tdir}/input.json" ] + if [ "${inputFile}" = "input.json" ] then - ! [ -e "${tdir}/stdin" ] || fail "Found a file called 'stdin' but redirecting standard input in JSON mode is not allowed." + ! [ -e "stdin" ] || fail "Found a file called 'stdin' but redirecting standard input in JSON mode is not allowed." stdin="${inputFile}" inputFile="" - stdout="$(cat "${tdir}/output.json" 2>/dev/null || true)" - stdoutExpectationFile="${tdir}/output.json" + stdout="$(cat "output.json" 2>/dev/null || true)" + stdoutExpectationFile="output.json" prettyPrintFlags="" - if [[ ! -f "${tdir}/no-pretty-print" ]] + if [[ ! -f "no-pretty-print" ]] then prettyPrintFlags="--pretty-json --json-indent 4" fi - command_args="--standard-json ${prettyPrintFlags} "$(cat "${tdir}/args" 2>/dev/null || true) + command_args="--standard-json ${prettyPrintFlags} "$(cat "args" 2>/dev/null || true) else - if [ -e "${tdir}/stdin" ] + if [ -e "stdin" ] then - stdin="${tdir}/stdin" - [ -f "${tdir}/stdin" ] || fail "'stdin' is not a regular file." + stdin="stdin" + [ -f "stdin" ] || fail "'stdin' is not a regular file." else stdin="" fi - stdout="$(cat "${tdir}/output" 2>/dev/null || true)" - stdoutExpectationFile="${tdir}/output" - command_args=$(cat "${tdir}/args" 2>/dev/null || true) + stdout="$(cat "output" 2>/dev/null || true)" + stdoutExpectationFile="output" + command_args=$(cat "args" 2>/dev/null || true) fi - exitCodeExpectationFile="${tdir}/exit" + exitCodeExpectationFile="exit" exitCode=$(cat "$exitCodeExpectationFile" 2>/dev/null || true) - err="$(cat "${tdir}/err" 2>/dev/null || true)" - stderrExpectationFile="${tdir}/err" + err="$(cat "err" 2>/dev/null || true)" + stderrExpectationFile="err" test_solc_behaviour "$inputFile" \ "$command_args" \ "$stdin" \ From 2fa170efc1517f1ddc82c24d015c95d82f4c1534 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 10 Apr 2025 15:26:42 +0200 Subject: [PATCH 056/121] update test expectations with cwd being in test dir --- test/cmdlineTests/abi_via_ir/output | 4 +- .../abiencoderv2_no_warning/output | 2 +- test/cmdlineTests/asm_json/output | 4 +- .../asm_json_no_pretty_print/output | 4 +- .../ast_compact_json_no_pretty_json/output | 4 +- .../output | 4 +- .../ast_compact_json_with_base_path/output | 10 +- test/cmdlineTests/ast_ir/output | 276 +++++++++--------- test/cmdlineTests/combined_json_abi/output | 2 +- .../combined_json_generated_sources/output | 2 +- .../combined_json_no_pretty_print/output | 2 +- .../combined_json_stop_after_parsing/output | 8 +- .../combined_json_with_base_path/output | 16 +- .../combined_json_with_devdoc/output | 4 +- .../combined_json_with_userdoc/output | 4 +- .../constant_optimizer_yul/output | 4 +- .../output | 16 +- .../output | 16 +- .../output | 10 +- .../debug_info_in_yul_snippet_escaping/output | 24 +- test/cmdlineTests/dup_opt_peephole/output | 18 +- test/cmdlineTests/error_codes/err | 12 +- .../ethdebug_eof_container_osaka/output | 4 +- test/cmdlineTests/events_in_abi/output | 4 +- test/cmdlineTests/evm_version_byzantium/err | 2 +- .../evm_version_constantinople/err | 2 +- .../evmasm_difficulty_post_paris/err | 2 +- .../evmasm_difficulty_post_paris/output | 2 +- .../evmasm_difficulty_pre_paris/output | 2 +- .../evmasm_prevrandao_post_paris/output | 2 +- .../evmasm_prevrandao_pre_paris/err | 2 +- .../evmasm_prevrandao_pre_paris/output | 2 +- .../err | 2 +- .../output | 2 +- .../err | 2 +- .../output | 2 +- .../output | 2 +- .../output | 2 +- test/cmdlineTests/exp_base_literal/output | 4 +- test/cmdlineTests/function_debug_info/output | 2 +- .../function_debug_info_via_yul/output | 2 +- test/cmdlineTests/hashes/output | 4 +- .../inline_assembly_function_name_clash/err | 4 +- .../output | 2 +- .../output | 8 +- test/cmdlineTests/ir_compiler_subobjects/err | 2 +- .../ir_compiler_subobjects/output | 12 +- .../output | 4 +- .../ir_optimized_with_optimize/output | 4 +- test/cmdlineTests/ir_subobject_order/output | 20 +- .../ir_unoptimized_with_optimize/output | 4 +- .../output | 4 +- .../output | 4 +- .../output | 4 +- .../keccak_optimization_deploy_code/output | 4 +- .../keccak_optimization_low_runs/output | 4 +- .../linking_qualified_library_name/args | 2 +- .../contract1.sol | 2 +- .../linking_qualified_library_name/output | 4 +- test/cmdlineTests/linking_solidity/args | 2 +- test/cmdlineTests/linking_solidity/output | 4 +- .../args | 2 +- .../output | 18 +- .../linking_strict_assembly/output | 10 +- .../output | 2 +- .../output | 2 +- .../output | 18 +- .../output | 18 +- .../output | 2 +- .../output | 2 +- .../output | 18 +- .../linking_unqualified_library_name/args | 2 +- .../contract1.sol | 2 +- .../contract2.sol | 2 +- .../linking_unqualified_library_name/output | 16 +- .../mcopy_bytes_array_abi_decode/err | 2 +- .../mcopy_bytes_array_abi_decode/output | 4 +- .../output | 4 +- .../output | 4 +- .../output | 4 +- test/cmdlineTests/message_format/err | 18 +- test/cmdlineTests/message_format_utf8/err | 10 +- test/cmdlineTests/metadata/output | 4 +- .../model_checker_bmc_loop_iterations/err | 2 +- .../err | 2 +- .../model_checker_contracts_all/err | 4 +- .../model_checker_contracts_all_explicit/args | 2 +- .../model_checker_contracts_all_explicit/err | 4 +- .../args | 2 +- .../err | 2 +- .../args | 2 +- .../err | 2 +- .../args | 2 +- .../err | 2 +- .../model_checker_contracts_only_one/args | 2 +- .../model_checker_contracts_only_one/err | 4 +- .../cmdlineTests/model_checker_engine_all/err | 2 +- .../cmdlineTests/model_checker_engine_bmc/err | 2 +- .../cmdlineTests/model_checker_engine_chc/err | 2 +- .../model_checker_ext_calls_trusted_chc/err | 2 +- .../model_checker_ext_calls_untrusted_chc/err | 2 +- .../model_checker_invariants_all/err | 4 +- .../model_checker_invariants_contract/err | 2 +- .../model_checker_invariants_contract_eld/err | 2 +- .../err | 4 +- .../model_checker_invariants_reentrancy/err | 2 +- .../err | 2 +- .../err | 2 +- .../err | 2 +- .../err | 6 +- .../err | 6 +- .../err | 6 +- .../err | 2 +- .../model_checker_show_unproved_true_chc/err | 2 +- .../err | 2 +- .../err | 2 +- .../err | 2 +- .../model_checker_solvers_cvc5/err | 2 +- .../model_checker_solvers_cvc5_eld/err | 2 +- .../model_checker_solvers_eld/err | 2 +- .../cmdlineTests/model_checker_solvers_z3/err | 2 +- .../model_checker_solvers_z3_implicit/err | 2 +- .../model_checker_solvers_z3_smtlib2/err | 2 +- .../model_checker_targets_all_all_engines/err | 14 +- .../model_checker_targets_all_bmc/err | 12 +- .../model_checker_targets_all_chc/err | 12 +- .../model_checker_targets_assert_bmc/err | 2 +- .../model_checker_targets_assert_chc/err | 2 +- .../model_checker_targets_balance_bmc/err | 2 +- .../err | 2 +- .../err | 10 +- .../model_checker_targets_default_bmc/err | 8 +- .../model_checker_targets_default_chc/err | 8 +- .../model_checker_targets_div_by_zero_bmc/err | 2 +- .../model_checker_targets_div_by_zero_chc/err | 2 +- .../err | 2 +- .../model_checker_targets_overflow_bmc/err | 2 +- .../model_checker_targets_overflow_chc/err | 2 +- .../model_checker_targets_pop_empty_chc/err | 2 +- .../model_checker_targets_underflow_bmc/err | 2 +- .../model_checker_targets_underflow_chc/err | 2 +- .../err | 6 +- .../err | 6 +- .../err | 4 +- .../err | 4 +- test/cmdlineTests/name_simplifier/output | 4 +- test/cmdlineTests/no_cbor_metadata/output | 2 +- .../no_contract_combined_json/output | 6 +- test/cmdlineTests/no_import_callback/args | 2 +- test/cmdlineTests/no_import_callback/err | 2 +- test/cmdlineTests/object_compiler/output | 34 +-- .../optimize_full_storage_write/output | 16 +- .../optimizer_BlockDeDuplicator/err | 4 +- .../optimizer_BlockDeDuplicator/output | 20 +- .../cmdlineTests/optimizer_array_sload/output | 4 +- .../cmdlineTests/optimizer_inliner_add/output | 30 +- .../output | 24 +- .../output | 58 ++-- .../output | 66 ++--- .../cmdlineTests/optimizer_inliner_inc/output | 28 +- .../optimizer_inliner_multireturn/output | 30 +- test/cmdlineTests/optimizer_user_yul/output | 56 ++-- test/cmdlineTests/require_overload/err | 2 +- .../cmdlineTests/require_with_error_ir/output | 4 +- .../require_with_string_ir/output | 4 +- test/cmdlineTests/revert_strings/output | 4 +- .../stack_too_deep_from_code_transform/err | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../standard_ir_ast_requested/input.json | 2 +- .../cmdlineTests/standard_metadata/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../standard_optimizer_no_yul/input.json | 2 +- .../standard_optimizer_yul/input.json | 2 +- .../standard_optimizer_yulDetails/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 6 +- .../output.json | 4 +- .../standard_urls_missing/input.json | 6 +- .../standard_urls_missing/output.json | 12 +- .../standard_yul_cfg_json_export/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../standard_yul_ethdebug_ir/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../stop_after_parsing_ast/output | 4 +- .../input.json | 2 +- .../storage_layout_user_defined/err | 2 +- .../storage_layout_user_defined/output | 18 +- .../output | 2 +- .../strict_asm_ast_compact_json/output | 2 +- .../strict_asm_debug_info_print_all/output | 2 +- .../output | 2 +- .../strict_asm_debug_info_print_none/output | 2 +- .../strict_asm_eof_container_osaka/output | 2 +- .../strict_asm_eof_dataloadn_osaka/output | 2 +- .../strict_asm_evm_version_byzantium/output | 4 +- .../output | 4 +- test/cmdlineTests/strict_asm_jump/err | 2 +- .../strict_asm_msize_with_optimizer/output | 2 +- .../strict_asm_msize_without_optimizer/output | 2 +- test/cmdlineTests/strict_asm_only_cr/err | 2 +- .../strict_asm_optimizer_steps/output | 50 ++-- .../output | 10 +- .../output | 2 +- .../output | 2 +- test/cmdlineTests/strict_asm_warning/err | 2 +- test/cmdlineTests/strict_asm_warning/output | 2 +- .../strict_asm_warning_and_error_optimize/err | 4 +- .../strict_asm_warning_optimize/err | 2 +- .../strict_asm_warning_optimize/output | 2 +- .../err | 2 +- .../output | 2 +- .../strict_asm_yul_cfg_json_export/output | 2 +- .../err | 4 +- test/cmdlineTests/too_long_line/err | 2 +- .../too_long_line_both_sides_short/err | 2 +- test/cmdlineTests/too_long_line_edge_in/err | 2 +- test/cmdlineTests/too_long_line_edge_out/err | 2 +- .../cmdlineTests/too_long_line_left_short/err | 2 +- test/cmdlineTests/too_long_line_multiline/err | 2 +- .../too_long_line_right_short/err | 2 +- .../transient_storage_layout/output | 12 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../output | 4 +- test/cmdlineTests/viair_abicoder_v1/err | 2 +- test/cmdlineTests/viair_abicoder_v1/output | 4 +- .../viair_msize_without_optimizer/output | 6 +- .../viair_subobject_optimization/output | 56 ++-- test/cmdlineTests/viair_subobjects/err | 2 +- test/cmdlineTests/viair_subobjects/output | 16 +- test/cmdlineTests/yul_cfg_json_export/output | 6 +- .../yul_function_name_clashes/output | 2 +- .../output | 28 +- test/cmdlineTests/yul_optimize_runs/output | 22 +- .../output | 4 +- test/cmdlineTests/yul_optimizer_steps/output | 4 +- .../output | 4 +- .../yul_optimizer_steps_short_sequence/output | 4 +- .../output | 4 +- .../output | 4 +- .../err | 4 +- .../output | 8 +- test/cmdlineTests/yul_verbatim/output | 34 +-- test/cmdlineTests/yul_verbatim_msize/output | 18 +- 291 files changed, 959 insertions(+), 959 deletions(-) diff --git a/test/cmdlineTests/abi_via_ir/output b/test/cmdlineTests/abi_via_ir/output index 56ba01a4a248..3b3fec68d93b 100644 --- a/test/cmdlineTests/abi_via_ir/output +++ b/test/cmdlineTests/abi_via_ir/output @@ -1,5 +1,5 @@ -======= abi_via_ir/input.sol:C ======= +======= input.sol:C ======= Contract JSON ABI [ { @@ -101,7 +101,7 @@ Contract JSON ABI } ] -======= abi_via_ir/input.sol:L ======= +======= input.sol:L ======= Contract JSON ABI [ { diff --git a/test/cmdlineTests/abiencoderv2_no_warning/output b/test/cmdlineTests/abiencoderv2_no_warning/output index 33f8d2e1fa8f..5b99567cc0fb 100644 --- a/test/cmdlineTests/abiencoderv2_no_warning/output +++ b/test/cmdlineTests/abiencoderv2_no_warning/output @@ -1,4 +1,4 @@ -======= abiencoderv2_no_warning/input.sol:C ======= +======= input.sol:C ======= Function signatures: 3fc03eeb: f((uint256)) diff --git a/test/cmdlineTests/asm_json/output b/test/cmdlineTests/asm_json/output index 820eda6ec4a6..a148e42f0ca7 100644 --- a/test/cmdlineTests/asm_json/output +++ b/test/cmdlineTests/asm_json/output @@ -1,5 +1,5 @@ -======= asm_json/input.sol:C ======= +======= input.sol:C ======= EVM assembly: { ".code": [ @@ -1573,7 +1573,7 @@ EVM assembly: } }, "sourceList": [ - "asm_json/input.sol", + "input.sol", "#utility.yul" ] } diff --git a/test/cmdlineTests/asm_json_no_pretty_print/output b/test/cmdlineTests/asm_json_no_pretty_print/output index 8fce2f4827d9..b2382e1866b5 100644 --- a/test/cmdlineTests/asm_json_no_pretty_print/output +++ b/test/cmdlineTests/asm_json_no_pretty_print/output @@ -1,4 +1,4 @@ -======= asm_json_no_pretty_print/input.sol:C ======= +======= input.sol:C ======= EVM assembly: -{".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH #[$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH [$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CODECOPY","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"RETURN","source":0}],".data":{"0":{".auxdata":"",".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"4"},{"begin":60,"end":160,"name":"CALLDATASIZE","source":0},{"begin":60,"end":160,"name":"LT","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CALLDATALOAD","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"E0"},{"begin":60,"end":160,"name":"SHR","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"B3DE648B"},{"begin":60,"end":160,"name":"EQ","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"3"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"3"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"4"},{"begin":77,"end":158,"name":"PUSH","source":0,"value":"4"},{"begin":77,"end":158,"name":"DUP1","source":0},{"begin":77,"end":158,"name":"CALLDATASIZE","source":0},{"begin":77,"end":158,"name":"SUB","source":0},{"begin":77,"end":158,"name":"DUP2","source":0},{"begin":77,"end":158,"name":"ADD","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"5"},{"begin":77,"end":158,"name":"SWAP2","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"6"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"5"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"7"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"4"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"STOP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"7"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":123,"end":125,"name":"PUSH","source":0,"value":"2A"},{"begin":118,"end":125,"name":"DUP2","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"9"},{"begin":118,"end":125,"name":"SWAP2","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"10"},{"begin":118,"end":125,"jumpType":"[in]","name":"JUMP","source":0},{"begin":118,"end":125,"name":"tag","source":0,"value":"9"},{"begin":118,"end":125,"name":"JUMPDEST","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"POP","source":0},{"begin":147,"end":150,"name":"PUSH","source":0,"value":"64"},{"begin":143,"end":144,"name":"DUP2","source":0},{"begin":143,"end":150,"name":"GT","source":0},{"begin":135,"end":151,"name":"PUSH [tag]","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPI","source":0},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"REVERT","source":0},{"begin":135,"end":151,"name":"tag","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"POP","source":0},{"begin":77,"end":158,"jumpType":"[out]","name":"JUMP","source":0},{"begin":88,"end":205,"name":"tag","source":1,"value":"13"},{"begin":88,"end":205,"name":"JUMPDEST","source":1},{"begin":197,"end":198,"name":"PUSH","source":1,"value":"0"},{"begin":194,"end":195,"name":"PUSH","source":1,"value":"0"},{"begin":187,"end":199,"name":"REVERT","source":1},{"begin":334,"end":411,"name":"tag","source":1,"value":"15"},{"begin":334,"end":411,"name":"JUMPDEST","source":1},{"begin":371,"end":378,"name":"PUSH","source":1,"value":"0"},{"begin":400,"end":405,"name":"DUP2","source":1},{"begin":389,"end":405,"name":"SWAP1","source":1},{"begin":389,"end":405,"name":"POP","source":1},{"begin":334,"end":411,"name":"SWAP2","source":1},{"begin":334,"end":411,"name":"SWAP1","source":1},{"begin":334,"end":411,"name":"POP","source":1},{"begin":334,"end":411,"jumpType":"[out]","name":"JUMP","source":1},{"begin":417,"end":539,"name":"tag","source":1,"value":"16"},{"begin":417,"end":539,"name":"JUMPDEST","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"25"},{"begin":508,"end":513,"name":"DUP2","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":490,"end":514,"jumpType":"[in]","name":"JUMP","source":1},{"begin":490,"end":514,"name":"tag","source":1,"value":"25"},{"begin":490,"end":514,"name":"JUMPDEST","source":1},{"begin":483,"end":488,"name":"DUP2","source":1},{"begin":480,"end":515,"name":"EQ","source":1},{"begin":470,"end":533,"name":"PUSH [tag]","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPI","source":1},{"begin":529,"end":530,"name":"PUSH","source":1,"value":"0"},{"begin":526,"end":527,"name":"PUSH","source":1,"value":"0"},{"begin":519,"end":531,"name":"REVERT","source":1},{"begin":470,"end":533,"name":"tag","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPDEST","source":1},{"begin":417,"end":539,"name":"POP","source":1},{"begin":417,"end":539,"jumpType":"[out]","name":"JUMP","source":1},{"begin":545,"end":684,"name":"tag","source":1,"value":"17"},{"begin":545,"end":684,"name":"JUMPDEST","source":1},{"begin":591,"end":596,"name":"PUSH","source":1,"value":"0"},{"begin":629,"end":635,"name":"DUP2","source":1},{"begin":616,"end":636,"name":"CALLDATALOAD","source":1},{"begin":607,"end":636,"name":"SWAP1","source":1},{"begin":607,"end":636,"name":"POP","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"28"},{"begin":672,"end":677,"name":"DUP2","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"16"},{"begin":645,"end":678,"jumpType":"[in]","name":"JUMP","source":1},{"begin":645,"end":678,"name":"tag","source":1,"value":"28"},{"begin":645,"end":678,"name":"JUMPDEST","source":1},{"begin":545,"end":684,"name":"SWAP3","source":1},{"begin":545,"end":684,"name":"SWAP2","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"jumpType":"[out]","name":"JUMP","source":1},{"begin":690,"end":1019,"name":"tag","source":1,"value":"6"},{"begin":690,"end":1019,"name":"JUMPDEST","source":1},{"begin":749,"end":755,"name":"PUSH","source":1,"value":"0"},{"begin":798,"end":800,"name":"PUSH","source":1,"value":"20"},{"begin":786,"end":795,"name":"DUP3","source":1},{"begin":777,"end":784,"name":"DUP5","source":1},{"begin":773,"end":796,"name":"SUB","source":1},{"begin":769,"end":801,"name":"SLT","source":1},{"begin":766,"end":885,"name":"ISZERO","source":1},{"begin":766,"end":885,"name":"PUSH [tag]","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPI","source":1},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"31"},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"13"},{"begin":804,"end":883,"jumpType":"[in]","name":"JUMP","source":1},{"begin":804,"end":883,"name":"tag","source":1,"value":"31"},{"begin":804,"end":883,"name":"JUMPDEST","source":1},{"begin":766,"end":885,"name":"tag","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPDEST","source":1},{"begin":924,"end":925,"name":"PUSH","source":1,"value":"0"},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"32"},{"begin":994,"end":1001,"name":"DUP5","source":1},{"begin":985,"end":991,"name":"DUP3","source":1},{"begin":974,"end":983,"name":"DUP6","source":1},{"begin":970,"end":992,"name":"ADD","source":1},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"17"},{"begin":949,"end":1002,"jumpType":"[in]","name":"JUMP","source":1},{"begin":949,"end":1002,"name":"tag","source":1,"value":"32"},{"begin":949,"end":1002,"name":"JUMPDEST","source":1},{"begin":939,"end":1002,"name":"SWAP2","source":1},{"begin":939,"end":1002,"name":"POP","source":1},{"begin":895,"end":1012,"name":"POP","source":1},{"begin":690,"end":1019,"name":"SWAP3","source":1},{"begin":690,"end":1019,"name":"SWAP2","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"jumpType":"[out]","name":"JUMP","source":1},{"begin":1025,"end":1205,"name":"tag","source":1,"value":"18"},{"begin":1025,"end":1205,"name":"JUMPDEST","source":1},{"begin":1073,"end":1150,"name":"PUSH","source":1,"value":"4E487B7100000000000000000000000000000000000000000000000000000000"},{"begin":1070,"end":1071,"name":"PUSH","source":1,"value":"0"},{"begin":1063,"end":1151,"name":"MSTORE","source":1},{"begin":1170,"end":1174,"name":"PUSH","source":1,"value":"11"},{"begin":1167,"end":1168,"name":"PUSH","source":1,"value":"4"},{"begin":1160,"end":1175,"name":"MSTORE","source":1},{"begin":1194,"end":1198,"name":"PUSH","source":1,"value":"24"},{"begin":1191,"end":1192,"name":"PUSH","source":1,"value":"0"},{"begin":1184,"end":1199,"name":"REVERT","source":1},{"begin":1211,"end":1402,"name":"tag","source":1,"value":"10"},{"begin":1211,"end":1402,"name":"JUMPDEST","source":1},{"begin":1251,"end":1254,"name":"PUSH","source":1,"value":"0"},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"35"},{"begin":1288,"end":1289,"name":"DUP3","source":1},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1270,"end":1290,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1270,"end":1290,"name":"tag","source":1,"value":"35"},{"begin":1270,"end":1290,"name":"JUMPDEST","source":1},{"begin":1265,"end":1290,"name":"SWAP2","source":1},{"begin":1265,"end":1290,"name":"POP","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"36"},{"begin":1322,"end":1323,"name":"DUP4","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1304,"end":1324,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1304,"end":1324,"name":"tag","source":1,"value":"36"},{"begin":1304,"end":1324,"name":"JUMPDEST","source":1},{"begin":1299,"end":1324,"name":"SWAP3","source":1},{"begin":1299,"end":1324,"name":"POP","source":1},{"begin":1347,"end":1348,"name":"DUP3","source":1},{"begin":1344,"end":1345,"name":"DUP3","source":1},{"begin":1340,"end":1349,"name":"ADD","source":1},{"begin":1333,"end":1349,"name":"SWAP1","source":1},{"begin":1333,"end":1349,"name":"POP","source":1},{"begin":1368,"end":1371,"name":"DUP1","source":1},{"begin":1365,"end":1366,"name":"DUP3","source":1},{"begin":1362,"end":1372,"name":"GT","source":1},{"begin":1359,"end":1395,"name":"ISZERO","source":1},{"begin":1359,"end":1395,"name":"PUSH [tag]","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPI","source":1},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"18"},{"begin":1375,"end":1393,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1375,"end":1393,"name":"tag","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"JUMPDEST","source":1},{"begin":1359,"end":1395,"name":"tag","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPDEST","source":1},{"begin":1211,"end":1402,"name":"SWAP3","source":1},{"begin":1211,"end":1402,"name":"SWAP2","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"jumpType":"[out]","name":"JUMP","source":1}]}},"sourceList":["asm_json_no_pretty_print/input.sol","#utility.yul"]} +{".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH #[$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH [$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CODECOPY","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"RETURN","source":0}],".data":{"0":{".auxdata":"",".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"4"},{"begin":60,"end":160,"name":"CALLDATASIZE","source":0},{"begin":60,"end":160,"name":"LT","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CALLDATALOAD","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"E0"},{"begin":60,"end":160,"name":"SHR","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"B3DE648B"},{"begin":60,"end":160,"name":"EQ","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"3"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"3"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"4"},{"begin":77,"end":158,"name":"PUSH","source":0,"value":"4"},{"begin":77,"end":158,"name":"DUP1","source":0},{"begin":77,"end":158,"name":"CALLDATASIZE","source":0},{"begin":77,"end":158,"name":"SUB","source":0},{"begin":77,"end":158,"name":"DUP2","source":0},{"begin":77,"end":158,"name":"ADD","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"5"},{"begin":77,"end":158,"name":"SWAP2","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"6"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"5"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"7"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"4"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"STOP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"7"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":123,"end":125,"name":"PUSH","source":0,"value":"2A"},{"begin":118,"end":125,"name":"DUP2","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"9"},{"begin":118,"end":125,"name":"SWAP2","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"10"},{"begin":118,"end":125,"jumpType":"[in]","name":"JUMP","source":0},{"begin":118,"end":125,"name":"tag","source":0,"value":"9"},{"begin":118,"end":125,"name":"JUMPDEST","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"POP","source":0},{"begin":147,"end":150,"name":"PUSH","source":0,"value":"64"},{"begin":143,"end":144,"name":"DUP2","source":0},{"begin":143,"end":150,"name":"GT","source":0},{"begin":135,"end":151,"name":"PUSH [tag]","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPI","source":0},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"REVERT","source":0},{"begin":135,"end":151,"name":"tag","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"POP","source":0},{"begin":77,"end":158,"jumpType":"[out]","name":"JUMP","source":0},{"begin":88,"end":205,"name":"tag","source":1,"value":"13"},{"begin":88,"end":205,"name":"JUMPDEST","source":1},{"begin":197,"end":198,"name":"PUSH","source":1,"value":"0"},{"begin":194,"end":195,"name":"PUSH","source":1,"value":"0"},{"begin":187,"end":199,"name":"REVERT","source":1},{"begin":334,"end":411,"name":"tag","source":1,"value":"15"},{"begin":334,"end":411,"name":"JUMPDEST","source":1},{"begin":371,"end":378,"name":"PUSH","source":1,"value":"0"},{"begin":400,"end":405,"name":"DUP2","source":1},{"begin":389,"end":405,"name":"SWAP1","source":1},{"begin":389,"end":405,"name":"POP","source":1},{"begin":334,"end":411,"name":"SWAP2","source":1},{"begin":334,"end":411,"name":"SWAP1","source":1},{"begin":334,"end":411,"name":"POP","source":1},{"begin":334,"end":411,"jumpType":"[out]","name":"JUMP","source":1},{"begin":417,"end":539,"name":"tag","source":1,"value":"16"},{"begin":417,"end":539,"name":"JUMPDEST","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"25"},{"begin":508,"end":513,"name":"DUP2","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":490,"end":514,"jumpType":"[in]","name":"JUMP","source":1},{"begin":490,"end":514,"name":"tag","source":1,"value":"25"},{"begin":490,"end":514,"name":"JUMPDEST","source":1},{"begin":483,"end":488,"name":"DUP2","source":1},{"begin":480,"end":515,"name":"EQ","source":1},{"begin":470,"end":533,"name":"PUSH [tag]","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPI","source":1},{"begin":529,"end":530,"name":"PUSH","source":1,"value":"0"},{"begin":526,"end":527,"name":"PUSH","source":1,"value":"0"},{"begin":519,"end":531,"name":"REVERT","source":1},{"begin":470,"end":533,"name":"tag","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPDEST","source":1},{"begin":417,"end":539,"name":"POP","source":1},{"begin":417,"end":539,"jumpType":"[out]","name":"JUMP","source":1},{"begin":545,"end":684,"name":"tag","source":1,"value":"17"},{"begin":545,"end":684,"name":"JUMPDEST","source":1},{"begin":591,"end":596,"name":"PUSH","source":1,"value":"0"},{"begin":629,"end":635,"name":"DUP2","source":1},{"begin":616,"end":636,"name":"CALLDATALOAD","source":1},{"begin":607,"end":636,"name":"SWAP1","source":1},{"begin":607,"end":636,"name":"POP","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"28"},{"begin":672,"end":677,"name":"DUP2","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"16"},{"begin":645,"end":678,"jumpType":"[in]","name":"JUMP","source":1},{"begin":645,"end":678,"name":"tag","source":1,"value":"28"},{"begin":645,"end":678,"name":"JUMPDEST","source":1},{"begin":545,"end":684,"name":"SWAP3","source":1},{"begin":545,"end":684,"name":"SWAP2","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"jumpType":"[out]","name":"JUMP","source":1},{"begin":690,"end":1019,"name":"tag","source":1,"value":"6"},{"begin":690,"end":1019,"name":"JUMPDEST","source":1},{"begin":749,"end":755,"name":"PUSH","source":1,"value":"0"},{"begin":798,"end":800,"name":"PUSH","source":1,"value":"20"},{"begin":786,"end":795,"name":"DUP3","source":1},{"begin":777,"end":784,"name":"DUP5","source":1},{"begin":773,"end":796,"name":"SUB","source":1},{"begin":769,"end":801,"name":"SLT","source":1},{"begin":766,"end":885,"name":"ISZERO","source":1},{"begin":766,"end":885,"name":"PUSH [tag]","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPI","source":1},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"31"},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"13"},{"begin":804,"end":883,"jumpType":"[in]","name":"JUMP","source":1},{"begin":804,"end":883,"name":"tag","source":1,"value":"31"},{"begin":804,"end":883,"name":"JUMPDEST","source":1},{"begin":766,"end":885,"name":"tag","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPDEST","source":1},{"begin":924,"end":925,"name":"PUSH","source":1,"value":"0"},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"32"},{"begin":994,"end":1001,"name":"DUP5","source":1},{"begin":985,"end":991,"name":"DUP3","source":1},{"begin":974,"end":983,"name":"DUP6","source":1},{"begin":970,"end":992,"name":"ADD","source":1},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"17"},{"begin":949,"end":1002,"jumpType":"[in]","name":"JUMP","source":1},{"begin":949,"end":1002,"name":"tag","source":1,"value":"32"},{"begin":949,"end":1002,"name":"JUMPDEST","source":1},{"begin":939,"end":1002,"name":"SWAP2","source":1},{"begin":939,"end":1002,"name":"POP","source":1},{"begin":895,"end":1012,"name":"POP","source":1},{"begin":690,"end":1019,"name":"SWAP3","source":1},{"begin":690,"end":1019,"name":"SWAP2","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"jumpType":"[out]","name":"JUMP","source":1},{"begin":1025,"end":1205,"name":"tag","source":1,"value":"18"},{"begin":1025,"end":1205,"name":"JUMPDEST","source":1},{"begin":1073,"end":1150,"name":"PUSH","source":1,"value":"4E487B7100000000000000000000000000000000000000000000000000000000"},{"begin":1070,"end":1071,"name":"PUSH","source":1,"value":"0"},{"begin":1063,"end":1151,"name":"MSTORE","source":1},{"begin":1170,"end":1174,"name":"PUSH","source":1,"value":"11"},{"begin":1167,"end":1168,"name":"PUSH","source":1,"value":"4"},{"begin":1160,"end":1175,"name":"MSTORE","source":1},{"begin":1194,"end":1198,"name":"PUSH","source":1,"value":"24"},{"begin":1191,"end":1192,"name":"PUSH","source":1,"value":"0"},{"begin":1184,"end":1199,"name":"REVERT","source":1},{"begin":1211,"end":1402,"name":"tag","source":1,"value":"10"},{"begin":1211,"end":1402,"name":"JUMPDEST","source":1},{"begin":1251,"end":1254,"name":"PUSH","source":1,"value":"0"},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"35"},{"begin":1288,"end":1289,"name":"DUP3","source":1},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1270,"end":1290,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1270,"end":1290,"name":"tag","source":1,"value":"35"},{"begin":1270,"end":1290,"name":"JUMPDEST","source":1},{"begin":1265,"end":1290,"name":"SWAP2","source":1},{"begin":1265,"end":1290,"name":"POP","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"36"},{"begin":1322,"end":1323,"name":"DUP4","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1304,"end":1324,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1304,"end":1324,"name":"tag","source":1,"value":"36"},{"begin":1304,"end":1324,"name":"JUMPDEST","source":1},{"begin":1299,"end":1324,"name":"SWAP3","source":1},{"begin":1299,"end":1324,"name":"POP","source":1},{"begin":1347,"end":1348,"name":"DUP3","source":1},{"begin":1344,"end":1345,"name":"DUP3","source":1},{"begin":1340,"end":1349,"name":"ADD","source":1},{"begin":1333,"end":1349,"name":"SWAP1","source":1},{"begin":1333,"end":1349,"name":"POP","source":1},{"begin":1368,"end":1371,"name":"DUP1","source":1},{"begin":1365,"end":1366,"name":"DUP3","source":1},{"begin":1362,"end":1372,"name":"GT","source":1},{"begin":1359,"end":1395,"name":"ISZERO","source":1},{"begin":1359,"end":1395,"name":"PUSH [tag]","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPI","source":1},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"18"},{"begin":1375,"end":1393,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1375,"end":1393,"name":"tag","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"JUMPDEST","source":1},{"begin":1359,"end":1395,"name":"tag","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPDEST","source":1},{"begin":1211,"end":1402,"name":"SWAP3","source":1},{"begin":1211,"end":1402,"name":"SWAP2","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"jumpType":"[out]","name":"JUMP","source":1}]}},"sourceList":["input.sol","#utility.yul"]} diff --git a/test/cmdlineTests/ast_compact_json_no_pretty_json/output b/test/cmdlineTests/ast_compact_json_no_pretty_json/output index fb79fd524e24..43806c05506d 100644 --- a/test/cmdlineTests/ast_compact_json_no_pretty_json/output +++ b/test/cmdlineTests/ast_compact_json_no_pretty_json/output @@ -1,5 +1,5 @@ JSON AST (compact format): -======= ast_compact_json_no_pretty_json/input.sol ======= -{"absolutePath":"ast_compact_json_no_pretty_json/input.sol","exportedSymbols":{"C":[2]},"id":3,"license":"GPL-3.0","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"36:22:0"},{"abstract":false,"baseContracts":[],"canonicalName":"C","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":2,"linearizedBaseContracts":[2],"name":"C","nameLocation":"69:1:0","nodeType":"ContractDefinition","nodes":[],"scope":3,"src":"60:13:0","usedErrors":[],"usedEvents":[]}],"src":"36:38:0"} +======= input.sol ======= +{"absolutePath":"input.sol","exportedSymbols":{"C":[2]},"id":3,"license":"GPL-3.0","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"36:22:0"},{"abstract":false,"baseContracts":[],"canonicalName":"C","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":2,"linearizedBaseContracts":[2],"name":"C","nameLocation":"69:1:0","nodeType":"ContractDefinition","nodes":[],"scope":3,"src":"60:13:0","usedErrors":[],"usedEvents":[]}],"src":"36:38:0"} diff --git a/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output index 4fe5fe193be9..994286c3bbe4 100644 --- a/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output +++ b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output @@ -1,9 +1,9 @@ JSON AST (compact format): -======= ast_compact_json_storage_layout_specifier/input.sol ======= +======= input.sol ======= { - "absolutePath": "ast_compact_json_storage_layout_specifier/input.sol", + "absolutePath": "input.sol", "exportedSymbols": { "C": [ 6 diff --git a/test/cmdlineTests/ast_compact_json_with_base_path/output b/test/cmdlineTests/ast_compact_json_with_base_path/output index c61502020765..93f7df2536b6 100644 --- a/test/cmdlineTests/ast_compact_json_with_base_path/output +++ b/test/cmdlineTests/ast_compact_json_with_base_path/output @@ -1,9 +1,9 @@ JSON AST (compact format): -======= ast_compact_json_with_base_path/c.sol ======= +======= c.sol ======= { - "absolutePath": "ast_compact_json_with_base_path/c.sol", + "absolutePath": "c.sol", "exportedSymbols": { "C": [ 5 @@ -46,9 +46,9 @@ JSON AST (compact format): ], "src": "36:38:0" } -======= ast_compact_json_with_base_path/input.sol ======= +======= input.sol ======= { - "absolutePath": "ast_compact_json_with_base_path/input.sol", + "absolutePath": "input.sol", "exportedSymbols": { "C": [ 5 @@ -69,7 +69,7 @@ JSON AST (compact format): "src": "36:22:1" }, { - "absolutePath": "ast_compact_json_with_base_path/c.sol", + "absolutePath": "c.sol", "file": "./c.sol", "id": 2, "nameLocation": "-1:-1:-1", diff --git a/test/cmdlineTests/ast_ir/output b/test/cmdlineTests/ast_ir/output index 76f111990870..88047ade02b3 100644 --- a/test/cmdlineTests/ast_ir/output +++ b/test/cmdlineTests/ast_ir/output @@ -2,7 +2,7 @@ IR AST: { "code": { "block": { - "nativeSrc": "59:790:0", + "nativeSrc": "52:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -11,7 +11,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "118:2:0", + "nativeSrc": "111:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -21,7 +21,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "134:3:0", + "nativeSrc": "127:3:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -30,32 +30,32 @@ IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "122:11:0", + "nativeSrc": "115:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "122:16:0", + "nativeSrc": "115:16:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "111:6:0", + "nativeSrc": "104:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "111:28:0", + "nativeSrc": "104:28:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "111:28:0", + "nativeSrc": "104:28:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "163:83:0", + "nativeSrc": "156:83:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -64,15 +64,15 @@ IR AST: "arguments": [], "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "165:77:0", + "nativeSrc": "158:77:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "165:79:0", + "nativeSrc": "158:79:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "165:79:0", + "nativeSrc": "158:79:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -82,15 +82,15 @@ IR AST: "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "151:9:0", + "nativeSrc": "144:9:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "151:11:0", + "nativeSrc": "144:11:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "148:98:0", + "nativeSrc": "141:98:0", "nodeType": "YulIf", "src": "60:13:0" }, @@ -99,38 +99,38 @@ IR AST: "arguments": [], "functionName": { "name": "constructor_C_2", - "nativeSrc": "256:15:0", + "nativeSrc": "249:15:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "256:17:0", + "nativeSrc": "249:17:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "256:17:0", + "nativeSrc": "249:17:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { - "nativeSrc": "283:30:0", + "nativeSrc": "276:30:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { "arguments": [], "functionName": { "name": "allocate_unbounded", - "nativeSrc": "293:18:0", + "nativeSrc": "286:18:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "293:20:0", + "nativeSrc": "286:20:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "287:2:0", + "nativeSrc": "280:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -142,7 +142,7 @@ IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "331:2:0", + "nativeSrc": "324:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -151,7 +151,7 @@ IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "346:14:0", + "nativeSrc": "339:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -160,11 +160,11 @@ IR AST: ], "functionName": { "name": "dataoffset", - "nativeSrc": "335:10:0", + "nativeSrc": "328:10:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "335:26:0", + "nativeSrc": "328:26:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, @@ -173,7 +173,7 @@ IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "372:14:0", + "nativeSrc": "365:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -182,26 +182,26 @@ IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "363:8:0", + "nativeSrc": "356:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "363:24:0", + "nativeSrc": "356:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "322:8:0", + "nativeSrc": "315:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "322:66:0", + "nativeSrc": "315:66:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "322:66:0", + "nativeSrc": "315:66:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -210,7 +210,7 @@ IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "405:2:0", + "nativeSrc": "398:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -219,7 +219,7 @@ IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "418:14:0", + "nativeSrc": "411:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -228,44 +228,44 @@ IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "409:8:0", + "nativeSrc": "402:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "409:24:0", + "nativeSrc": "402:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "398:6:0", + "nativeSrc": "391:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "398:36:0", + "nativeSrc": "391:36:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "398:36:0", + "nativeSrc": "391:36:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "484:43:0", + "nativeSrc": "477:43:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ { - "nativeSrc": "498:19:0", + "nativeSrc": "491:19:0", "nodeType": "YulAssignment", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "514:2:0", + "nativeSrc": "507:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -274,18 +274,18 @@ IR AST: ], "functionName": { "name": "mload", - "nativeSrc": "508:5:0", + "nativeSrc": "501:5:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "508:9:0", + "nativeSrc": "501:9:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variableNames": [ { "name": "memPtr", - "nativeSrc": "498:6:0", + "nativeSrc": "491:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" } @@ -294,12 +294,12 @@ IR AST: ] }, "name": "allocate_unbounded", - "nativeSrc": "444:83:0", + "nativeSrc": "437:83:0", "nodeType": "YulFunctionDefinition", "returnVariables": [ { "name": "memPtr", - "nativeSrc": "477:6:0", + "nativeSrc": "470:6:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -309,7 +309,7 @@ IR AST: }, { "body": { - "nativeSrc": "626:36:0", + "nativeSrc": "619:36:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -318,7 +318,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "647:1:0", + "nativeSrc": "640:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -326,7 +326,7 @@ IR AST: }, { "kind": "number", - "nativeSrc": "650:1:0", + "nativeSrc": "643:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -335,34 +335,34 @@ IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "640:6:0", + "nativeSrc": "633:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "640:12:0", + "nativeSrc": "633:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "640:12:0", + "nativeSrc": "633:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } ] }, "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "537:125:0", + "nativeSrc": "530:125:0", "nodeType": "YulFunctionDefinition", "src": "60:13:0" }, { "body": { - "nativeSrc": "741:59:0", + "nativeSrc": "734:59:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [] }, "name": "constructor_C_2", - "nativeSrc": "714:86:0", + "nativeSrc": "707:86:0", "nodeType": "YulFunctionDefinition", "src": "60:13:0" } @@ -376,7 +376,7 @@ IR AST: { "code": { "block": { - "nativeSrc": "929:588:0", + "nativeSrc": "915:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -385,7 +385,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "996:2:0", + "nativeSrc": "982:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -395,7 +395,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "1012:3:0", + "nativeSrc": "998:3:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -404,26 +404,26 @@ IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "1000:11:0", + "nativeSrc": "986:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1000:16:0", + "nativeSrc": "986:16:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "989:6:0", + "nativeSrc": "975:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "989:28:0", + "nativeSrc": "975:28:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "989:28:0", + "nativeSrc": "975:28:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -432,33 +432,33 @@ IR AST: "arguments": [], "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "1031:77:0", + "nativeSrc": "1017:77:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1031:79:0", + "nativeSrc": "1017:79:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "1031:79:0", + "nativeSrc": "1017:79:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "1177:77:0", + "nativeSrc": "1163:77:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ { - "nativeSrc": "1195:44:0", + "nativeSrc": "1181:44:0", "nodeType": "YulAssignment", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "1228:3:0", + "nativeSrc": "1214:3:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -466,25 +466,25 @@ IR AST: }, { "name": "value", - "nativeSrc": "1233:5:0", + "nativeSrc": "1219:5:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "shr", - "nativeSrc": "1224:3:0", + "nativeSrc": "1210:3:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1224:15:0", + "nativeSrc": "1210:15:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variableNames": [ { "name": "newValue", - "nativeSrc": "1195:8:0", + "nativeSrc": "1181:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" } @@ -493,12 +493,12 @@ IR AST: ] }, "name": "shift_right_224_unsigned", - "nativeSrc": "1124:130:0", + "nativeSrc": "1110:130:0", "nodeType": "YulFunctionDefinition", "parameters": [ { "name": "value", - "nativeSrc": "1158:5:0", + "nativeSrc": "1144:5:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -507,7 +507,7 @@ IR AST: "returnVariables": [ { "name": "newValue", - "nativeSrc": "1168:8:0", + "nativeSrc": "1154:8:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -517,19 +517,19 @@ IR AST: }, { "body": { - "nativeSrc": "1308:51:0", + "nativeSrc": "1294:51:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ { - "nativeSrc": "1326:19:0", + "nativeSrc": "1312:19:0", "nodeType": "YulAssignment", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "1342:2:0", + "nativeSrc": "1328:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -538,18 +538,18 @@ IR AST: ], "functionName": { "name": "mload", - "nativeSrc": "1336:5:0", + "nativeSrc": "1322:5:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1336:9:0", + "nativeSrc": "1322:9:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variableNames": [ { "name": "memPtr", - "nativeSrc": "1326:6:0", + "nativeSrc": "1312:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" } @@ -558,12 +558,12 @@ IR AST: ] }, "name": "allocate_unbounded", - "nativeSrc": "1268:91:0", + "nativeSrc": "1254:91:0", "nodeType": "YulFunctionDefinition", "returnVariables": [ { "name": "memPtr", - "nativeSrc": "1301:6:0", + "nativeSrc": "1287:6:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -573,7 +573,7 @@ IR AST: }, { "body": { - "nativeSrc": "1462:44:0", + "nativeSrc": "1448:44:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -582,7 +582,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "1487:1:0", + "nativeSrc": "1473:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -590,7 +590,7 @@ IR AST: }, { "kind": "number", - "nativeSrc": "1490:1:0", + "nativeSrc": "1476:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -599,22 +599,22 @@ IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "1480:6:0", + "nativeSrc": "1466:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1480:12:0", + "nativeSrc": "1466:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "1480:12:0", + "nativeSrc": "1466:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } ] }, "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "1373:133:0", + "nativeSrc": "1359:133:0", "nodeType": "YulFunctionDefinition", "src": "60:13:0" } @@ -637,24 +637,24 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "58:315:0", + "nativeSrc": "51:315:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "68:299:0", + "nativeSrc": "61:299:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "128:27:0", + "nativeSrc": "121:27:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "150:4:0", + "nativeSrc": "143:4:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -663,18 +663,18 @@ Optimized IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "138:11:0", + "nativeSrc": "131:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "138:17:0", + "nativeSrc": "131:17:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "132:2:0", + "nativeSrc": "125:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -686,7 +686,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "175:2:0", + "nativeSrc": "168:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -694,28 +694,28 @@ Optimized IR AST: }, { "name": "_1", - "nativeSrc": "179:2:0", + "nativeSrc": "172:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "168:6:0", + "nativeSrc": "161:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "168:14:0", + "nativeSrc": "161:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "168:14:0", + "nativeSrc": "161:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "210:16:0", + "nativeSrc": "203:16:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -724,7 +724,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "219:1:0", + "nativeSrc": "212:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -732,7 +732,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "222:1:0", + "nativeSrc": "215:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -741,15 +741,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "212:6:0", + "nativeSrc": "205:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "212:12:0", + "nativeSrc": "205:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "212:12:0", + "nativeSrc": "205:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -759,20 +759,20 @@ Optimized IR AST: "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "198:9:0", + "nativeSrc": "191:9:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "198:11:0", + "nativeSrc": "191:11:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "195:31:0", + "nativeSrc": "188:31:0", "nodeType": "YulIf", "src": "60:13:0" }, { - "nativeSrc": "239:34:0", + "nativeSrc": "232:34:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { @@ -780,7 +780,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "258:14:0", + "nativeSrc": "251:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -789,18 +789,18 @@ Optimized IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "249:8:0", + "nativeSrc": "242:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "249:24:0", + "nativeSrc": "242:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_2", - "nativeSrc": "243:2:0", + "nativeSrc": "236:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -812,7 +812,7 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "295:2:0", + "nativeSrc": "288:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -821,7 +821,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "310:14:0", + "nativeSrc": "303:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -830,32 +830,32 @@ Optimized IR AST: ], "functionName": { "name": "dataoffset", - "nativeSrc": "299:10:0", + "nativeSrc": "292:10:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "299:26:0", + "nativeSrc": "292:26:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "327:2:0", + "nativeSrc": "320:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "286:8:0", + "nativeSrc": "279:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "286:44:0", + "nativeSrc": "279:44:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "286:44:0", + "nativeSrc": "279:44:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -864,28 +864,28 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "350:2:0", + "nativeSrc": "343:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "354:2:0", + "nativeSrc": "347:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "343:6:0", + "nativeSrc": "336:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "343:14:0", + "nativeSrc": "336:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "343:14:0", + "nativeSrc": "336:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -901,12 +901,12 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "453:118:0", + "nativeSrc": "439:118:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "467:94:0", + "nativeSrc": "453:94:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -915,7 +915,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "542:1:0", + "nativeSrc": "528:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -923,7 +923,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "545:1:0", + "nativeSrc": "531:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -932,15 +932,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "535:6:0", + "nativeSrc": "521:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "535:12:0", + "nativeSrc": "521:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "535:12:0", + "nativeSrc": "521:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } diff --git a/test/cmdlineTests/combined_json_abi/output b/test/cmdlineTests/combined_json_abi/output index 79b539db78d0..ee63ccb3ef6f 100644 --- a/test/cmdlineTests/combined_json_abi/output +++ b/test/cmdlineTests/combined_json_abi/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_abi/input.sol:C": { + "input.sol:C": { "abi": [] } }, diff --git a/test/cmdlineTests/combined_json_generated_sources/output b/test/cmdlineTests/combined_json_generated_sources/output index db7c86ce13d7..d863bd73a726 100644 --- a/test/cmdlineTests/combined_json_generated_sources/output +++ b/test/cmdlineTests/combined_json_generated_sources/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_generated_sources/input.sol:C": { + "input.sol:C": { "generated-sources": [], "generated-sources-runtime": [ { diff --git a/test/cmdlineTests/combined_json_no_pretty_print/output b/test/cmdlineTests/combined_json_no_pretty_print/output index 081dc4fa4eca..34c019b8f792 100644 --- a/test/cmdlineTests/combined_json_no_pretty_print/output +++ b/test/cmdlineTests/combined_json_no_pretty_print/output @@ -1 +1 @@ -{"contracts":{"combined_json_no_pretty_print/input.sol:C":{"abi":[]}},"version": ""} +{"contracts":{"input.sol:C":{"abi":[]}},"version": ""} diff --git a/test/cmdlineTests/combined_json_stop_after_parsing/output b/test/cmdlineTests/combined_json_stop_after_parsing/output index 64e66e3f1227..fa3707bf2488 100644 --- a/test/cmdlineTests/combined_json_stop_after_parsing/output +++ b/test/cmdlineTests/combined_json_stop_after_parsing/output @@ -1,14 +1,14 @@ { "contracts": { - "combined_json_stop_after_parsing/input.sol:C": {} + "input.sol:C": {} }, "sourceList": [ - "combined_json_stop_after_parsing/input.sol" + "input.sol" ], "sources": { - "combined_json_stop_after_parsing/input.sol": { + "input.sol": { "AST": { - "absolutePath": "combined_json_stop_after_parsing/input.sol", + "absolutePath": "input.sol", "id": 3, "license": "GPL-3.0", "nodeType": "SourceUnit", diff --git a/test/cmdlineTests/combined_json_with_base_path/output b/test/cmdlineTests/combined_json_with_base_path/output index 0a3add37e3b4..fe972a631a7a 100644 --- a/test/cmdlineTests/combined_json_with_base_path/output +++ b/test/cmdlineTests/combined_json_with_base_path/output @@ -1,15 +1,15 @@ { "contracts": { - "combined_json_with_base_path/c.sol:C": {} + "c.sol:C": {} }, "sourceList": [ - "combined_json_with_base_path/c.sol", - "combined_json_with_base_path/input.sol" + "c.sol", + "input.sol" ], "sources": { - "combined_json_with_base_path/c.sol": { + "c.sol": { "AST": { - "absolutePath": "combined_json_with_base_path/c.sol", + "absolutePath": "c.sol", "exportedSymbols": { "C": [ 5 @@ -54,9 +54,9 @@ }, "id": 0 }, - "combined_json_with_base_path/input.sol": { + "input.sol": { "AST": { - "absolutePath": "combined_json_with_base_path/input.sol", + "absolutePath": "input.sol", "exportedSymbols": { "C": [ 5 @@ -77,7 +77,7 @@ "src": "36:22:1" }, { - "absolutePath": "combined_json_with_base_path/c.sol", + "absolutePath": "c.sol", "file": "./c.sol", "id": 2, "nameLocation": "-1:-1:-1", diff --git a/test/cmdlineTests/combined_json_with_devdoc/output b/test/cmdlineTests/combined_json_with_devdoc/output index 817018ea6c58..482245fbc4b4 100644 --- a/test/cmdlineTests/combined_json_with_devdoc/output +++ b/test/cmdlineTests/combined_json_with_devdoc/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_with_devdoc/input.sol:C": { + "input.sol:C": { "devdoc": { "details": "This is devdoc.", "kind": "dev", @@ -8,7 +8,7 @@ "version": 1 } }, - "combined_json_with_devdoc/input.sol:D": { + "input.sol:D": { "devdoc": { "kind": "dev", "methods": {}, diff --git a/test/cmdlineTests/combined_json_with_userdoc/output b/test/cmdlineTests/combined_json_with_userdoc/output index 4eb56fe24dd2..0e28af093c1c 100644 --- a/test/cmdlineTests/combined_json_with_userdoc/output +++ b/test/cmdlineTests/combined_json_with_userdoc/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_with_userdoc/input.sol:C": { + "input.sol:C": { "userdoc": { "kind": "user", "methods": {}, @@ -8,7 +8,7 @@ "version": 1 } }, - "combined_json_with_userdoc/input.sol:D": { + "input.sol:D": { "userdoc": { "kind": "user", "methods": {}, diff --git a/test/cmdlineTests/constant_optimizer_yul/output b/test/cmdlineTests/constant_optimizer_yul/output index 9c7faa732272..c0d3ab934641 100644 --- a/test/cmdlineTests/constant_optimizer_yul/output +++ b/test/cmdlineTests/constant_optimizer_yul/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"constant_optimizer_yul/input.sol" +/// @use-src 0:"input.sol" object "C_12" { code { { @@ -15,7 +15,7 @@ object "C_12" { return(_1, _2) } } - /// @use-src 0:"constant_optimizer_yul/input.sol" + /// @use-src 0:"input.sol" object "C_12_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output index 4833a9f620a7..7ad569ba1107 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output @@ -1,7 +1,7 @@ -======= debug_info_in_yul_and_evm_asm_print_all/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */ + /* "input.sol":60:101 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */ + /* "input.sol":60:101 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "debug_info_in_yul_and_evm_asm_print_all/input.sol":77:99 function f() public {} */ + /* "input.sol":77:99 function f() public {} */ tag_3: stop @@ -49,7 +49,7 @@ sub_0: assembly { IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { /// @src 0:60:101 "contract C {..." @@ -80,7 +80,7 @@ object "C_6" { /// @src 0:60:101 "contract C {..." } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { /// @src 0:60:101 "contract C {..." @@ -163,7 +163,7 @@ object "C_6" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -176,7 +176,7 @@ object "C_6" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output index 00b04a01ad1f..36ef4d8294ab 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output @@ -1,7 +1,7 @@ -======= debug_info_in_yul_and_evm_asm_print_location_only/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */ + /* "input.sol":60:101 */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */ + /* "input.sol":60:101 */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":77:99 */ + /* "input.sol":77:99 */ tag_3: stop @@ -49,7 +49,7 @@ sub_0: assembly { IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { /// @src 0:60:101 @@ -80,7 +80,7 @@ object "C_6" { /// @src 0:60:101 } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { /// @src 0:60:101 @@ -162,7 +162,7 @@ object "C_6" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -175,7 +175,7 @@ object "C_6" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output index 9527edf769a4..ea3cb35a2849 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output @@ -1,5 +1,5 @@ -======= debug_info_in_yul_and_evm_asm_print_none/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) callvalue @@ -46,7 +46,7 @@ sub_0: assembly { IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { @@ -73,7 +73,7 @@ object "C_6" { } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { @@ -153,7 +153,7 @@ object "C_6" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -165,7 +165,7 @@ object "C_6" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index 975582f669ba..c29dfd89265d 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { /// @src 0:265:278 "contract C {}" @@ -31,7 +31,7 @@ object "C_2" { /// @src 0:265:278 "contract C {}" } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" @@ -63,7 +63,7 @@ object "C_2" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { { @@ -76,7 +76,7 @@ object "C_2" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { { @@ -90,7 +90,7 @@ object "C_2" { IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "D_27" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." @@ -121,7 +121,7 @@ object "D_27" { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "D_27_deployed" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." @@ -342,7 +342,7 @@ object "D_27" { } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2" { code { /// @src 0:265:278 "contract C {}" @@ -373,7 +373,7 @@ object "D_27" { /// @src 0:265:278 "contract C {}" } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" @@ -410,7 +410,7 @@ object "D_27" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "D_27" { code { { @@ -423,7 +423,7 @@ object "D_27" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "D_27_deployed" { code { { @@ -499,7 +499,7 @@ object "D_27" { revert(0, 0) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2" { code { { @@ -512,7 +512,7 @@ object "D_27" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { { diff --git a/test/cmdlineTests/dup_opt_peephole/output b/test/cmdlineTests/dup_opt_peephole/output index a9e0203ed1ff..f53e9e2bdb17 100644 --- a/test/cmdlineTests/dup_opt_peephole/output +++ b/test/cmdlineTests/dup_opt_peephole/output @@ -1,7 +1,7 @@ -======= dup_opt_peephole/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "dup_opt_peephole/input.sol":60:171 contract C {... */ + /* "input.sol":60:171 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "dup_opt_peephole/input.sol":60:171 contract C {... */ + /* "input.sol":60:171 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -31,17 +31,17 @@ sub_0: assembly { revert(0x00, 0x00) tag_3: pop - /* "dup_opt_peephole/input.sol":134:135 0 */ + /* "input.sol":134:135 0 */ 0x00 - /* "dup_opt_peephole/input.sol":121:136 calldataload(0) */ + /* "input.sol":121:136 calldataload(0) */ calldataload - /* "dup_opt_peephole/input.sol":160:161 x */ + /* "input.sol":160:161 x */ dup1 - /* "dup_opt_peephole/input.sol":157:158 0 */ + /* "input.sol":157:158 0 */ 0x00 - /* "dup_opt_peephole/input.sol":150:162 sstore(0, x) */ + /* "input.sol":150:162 sstore(0, x) */ sstore - /* "dup_opt_peephole/input.sol":107:166 {... */ + /* "input.sol":107:166 {... */ stop auxdata: diff --git a/test/cmdlineTests/error_codes/err b/test/cmdlineTests/error_codes/err index a10362a863a8..f3f6fe33905c 100644 --- a/test/cmdlineTests/error_codes/err +++ b/test/cmdlineTests/error_codes/err @@ -1,29 +1,29 @@ Warning (1878): SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information. ---> error_codes/input.sol +--> input.sol Error (4937): No visibility specified. Did you intend to add "public"? - --> error_codes/input.sol:2:5: + --> input.sol:2:5: | 2 | function f() { | ^ (Relevant source part starts here and spans across multiple lines). Warning (3420): Source file does not specify required compiler version! ---> error_codes/input.sol +--> input.sol Error (4247): Expression has to be an lvalue. - --> error_codes/input.sol:3:9: + --> input.sol:3:9: | 3 | 2=0; | ^ Error (7407): Type int_const 0 is not implicitly convertible to expected type int_const 2. - --> error_codes/input.sol:3:11: + --> input.sol:3:11: | 3 | 2=0; | ^ Error (2614): Indexed expression has to be a type, mapping or array (is literal_string "") - --> error_codes/input.sol:4:9: + --> input.sol:4:9: | 4 | ""[2]; | ^^ diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/output b/test/cmdlineTests/ethdebug_eof_container_osaka/output index 9d002fadc317..b29297ee3749 100644 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/output +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/output @@ -1,4 +1,4 @@ ======= Debug Data (ethdebug/format/info/resources) ======= -{"compilation":{"compiler":{"name":"solc","version": ""},"sources":[{"id":0,"path":"ethdebug_eof_container_osaka/input.sol"}]}} +{"compilation":{"compiler":{"name":"solc","version": ""},"sources":[{"id":0,"path":"input.sol"}]}} -======= ethdebug_eof_container_osaka/input.sol:C ======= +======= input.sol:C ======= diff --git a/test/cmdlineTests/events_in_abi/output b/test/cmdlineTests/events_in_abi/output index ab246ef24a15..220e65ef4a9f 100644 --- a/test/cmdlineTests/events_in_abi/output +++ b/test/cmdlineTests/events_in_abi/output @@ -1,5 +1,5 @@ -======= events_in_abi/input.sol:C ======= +======= input.sol:C ======= Contract JSON ABI [ { @@ -37,7 +37,7 @@ Contract JSON ABI } ] -======= events_in_abi/input.sol:L ======= +======= input.sol:L ======= Contract JSON ABI [ { diff --git a/test/cmdlineTests/evm_version_byzantium/err b/test/cmdlineTests/evm_version_byzantium/err index accbb596cb25..6815a852460a 100644 --- a/test/cmdlineTests/evm_version_byzantium/err +++ b/test/cmdlineTests/evm_version_byzantium/err @@ -1,3 +1,3 @@ Warning: Support for EVM versions older than constantinople is deprecated and will be removed in the future. Warning: Source file does not specify required compiler version! ---> evm_version_byzantium/input.sol +--> input.sol diff --git a/test/cmdlineTests/evm_version_constantinople/err b/test/cmdlineTests/evm_version_constantinople/err index 69f328f54efd..e3815925acb9 100644 --- a/test/cmdlineTests/evm_version_constantinople/err +++ b/test/cmdlineTests/evm_version_constantinople/err @@ -1,2 +1,2 @@ Warning: Source file does not specify required compiler version! ---> evm_version_constantinople/input.sol +--> input.sol diff --git a/test/cmdlineTests/evmasm_difficulty_post_paris/err b/test/cmdlineTests/evmasm_difficulty_post_paris/err index d8210184e1b0..8498f4c460c7 100644 --- a/test/cmdlineTests/evmasm_difficulty_post_paris/err +++ b/test/cmdlineTests/evmasm_difficulty_post_paris/err @@ -1,5 +1,5 @@ Warning: Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. - --> evmasm_difficulty_post_paris/input.sol:6:21: + --> input.sol:6:21: | 6 | uint256 x = block.difficulty; | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/evmasm_difficulty_post_paris/output b/test/cmdlineTests/evmasm_difficulty_post_paris/output index f8c1611e0274..6ade453b9735 100644 --- a/test/cmdlineTests/evmasm_difficulty_post_paris/output +++ b/test/cmdlineTests/evmasm_difficulty_post_paris/output @@ -1,5 +1,5 @@ -======= evmasm_difficulty_post_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, prevrandao) stop diff --git a/test/cmdlineTests/evmasm_difficulty_pre_paris/output b/test/cmdlineTests/evmasm_difficulty_pre_paris/output index ad75355f5bcb..26456f276fb7 100644 --- a/test/cmdlineTests/evmasm_difficulty_pre_paris/output +++ b/test/cmdlineTests/evmasm_difficulty_pre_paris/output @@ -1,5 +1,5 @@ -======= evmasm_difficulty_pre_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, difficulty) stop diff --git a/test/cmdlineTests/evmasm_prevrandao_post_paris/output b/test/cmdlineTests/evmasm_prevrandao_post_paris/output index 47c85bb50fcd..6ade453b9735 100644 --- a/test/cmdlineTests/evmasm_prevrandao_post_paris/output +++ b/test/cmdlineTests/evmasm_prevrandao_post_paris/output @@ -1,5 +1,5 @@ -======= evmasm_prevrandao_post_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, prevrandao) stop diff --git a/test/cmdlineTests/evmasm_prevrandao_pre_paris/err b/test/cmdlineTests/evmasm_prevrandao_pre_paris/err index 5970ec202066..429c06395086 100644 --- a/test/cmdlineTests/evmasm_prevrandao_pre_paris/err +++ b/test/cmdlineTests/evmasm_prevrandao_pre_paris/err @@ -1,5 +1,5 @@ Warning: "prevrandao" is not supported by the VM version and will be treated as "difficulty". - --> evmasm_prevrandao_pre_paris/input.sol:6:21: + --> input.sol:6:21: | 6 | uint256 x = block.prevrandao; | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/evmasm_prevrandao_pre_paris/output b/test/cmdlineTests/evmasm_prevrandao_pre_paris/output index e41148a8331a..26456f276fb7 100644 --- a/test/cmdlineTests/evmasm_prevrandao_pre_paris/output +++ b/test/cmdlineTests/evmasm_prevrandao_pre_paris/output @@ -1,5 +1,5 @@ -======= evmasm_prevrandao_pre_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, difficulty) stop diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err index 2e52d9ced0c6..6b7f432f2c92 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err @@ -1,5 +1,5 @@ Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. - --> evmasm_transient_storage_inline_assembly/input.sol:7:13: + --> input.sol:7:13: | 7 | tstore(0, 123) | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output index 0b4c516baef3..adeb0822c610 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_inline_assembly/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) callvalue diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err index 154da21b6577..6b7f432f2c92 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err @@ -1,5 +1,5 @@ Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. - --> evmasm_transient_storage_inline_assembly_via_ir/input.sol:7:13: + --> input.sol:7:13: | 7 | tstore(0, 123) | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output index 673bdd0a052d..754bc9d455a7 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_inline_assembly_via_ir/input.sol:C ======= +======= input.sol:C ======= EVM assembly: 0x80 dup1 diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable/output b/test/cmdlineTests/evmasm_transient_storage_state_variable/output index e80eb3c57fc7..0f2580c80564 100644 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable/output +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_state_variable/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) callvalue diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output index 5959fad952f1..b2f55e1d5724 100644 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_state_variable_via_ir/input.sol:C ======= +======= input.sol:C ======= EVM assembly: 0x80 dup1 diff --git a/test/cmdlineTests/exp_base_literal/output b/test/cmdlineTests/exp_base_literal/output index 24e5d29be756..fb5b35ed0fba 100644 --- a/test/cmdlineTests/exp_base_literal/output +++ b/test/cmdlineTests/exp_base_literal/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"exp_base_literal/input.sol" +/// @use-src 0:"input.sol" object "C_81" { code { /// @src 0:82:370 "contract C {..." @@ -31,7 +31,7 @@ object "C_81" { /// @src 0:82:370 "contract C {..." } - /// @use-src 0:"exp_base_literal/input.sol" + /// @use-src 0:"input.sol" object "C_81_deployed" { code { /// @src 0:82:370 "contract C {..." diff --git a/test/cmdlineTests/function_debug_info/output b/test/cmdlineTests/function_debug_info/output index c1346e33ab0c..aa4512352623 100644 --- a/test/cmdlineTests/function_debug_info/output +++ b/test/cmdlineTests/function_debug_info/output @@ -1,6 +1,6 @@ { "contracts": { - "function_debug_info/input.sol:C": { + "input.sol:C": { "function-debug": { "@_34": { "id": 34, diff --git a/test/cmdlineTests/function_debug_info_via_yul/output b/test/cmdlineTests/function_debug_info_via_yul/output index 05c2da48c607..c3a828ab30f0 100644 --- a/test/cmdlineTests/function_debug_info_via_yul/output +++ b/test/cmdlineTests/function_debug_info_via_yul/output @@ -1,6 +1,6 @@ { "contracts": { - "function_debug_info_via_yul/input.sol:C": { + "input.sol:C": { "function-debug": {}, "function-debug-runtime": {} } diff --git a/test/cmdlineTests/hashes/output b/test/cmdlineTests/hashes/output index b010456d3901..45eb1835900a 100644 --- a/test/cmdlineTests/hashes/output +++ b/test/cmdlineTests/hashes/output @@ -1,5 +1,5 @@ -======= hashes/input.sol:C ======= +======= input.sol:C ======= Function signatures: 3fc03eeb: f((uint256)) @@ -12,7 +12,7 @@ Event signatures: 2d4dd5fe18ada5a020a9f5591539a8dc3010a5c074ba6a70e1c956659f02786a: ev(uint256) 81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256) -======= hashes/input.sol:L ======= +======= input.sol:L ======= Function signatures: Error signatures: diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/err b/test/cmdlineTests/inline_assembly_function_name_clash/err index 5284ffe5ca89..892a312d0f26 100644 --- a/test/cmdlineTests/inline_assembly_function_name_clash/err +++ b/test/cmdlineTests/inline_assembly_function_name_clash/err @@ -1,5 +1,5 @@ Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information. ---> inline_assembly_function_name_clash/input.sol +--> input.sol Warning: Source file does not specify required compiler version! ---> inline_assembly_function_name_clash/input.sol +--> input.sol diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/output b/test/cmdlineTests/inline_assembly_function_name_clash/output index 2fd6ff1f5592..d21576ff0ba0 100644 --- a/test/cmdlineTests/inline_assembly_function_name_clash/output +++ b/test/cmdlineTests/inline_assembly_function_name_clash/output @@ -1,6 +1,6 @@ { "contracts": { - "inline_assembly_function_name_clash/input.sol:C": { + "input.sol:C": { "function-debug-runtime": { "abi_decode": { "entryPoint": 80, diff --git a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output index 84fd9d0bc35f..2d715d0abaad 100644 --- a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output +++ b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { { @@ -12,7 +12,7 @@ object "C_7" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { { @@ -25,7 +25,7 @@ object "C_7" { } Optimized IR: -/// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" +/// @use-src 0:"input.sol" object "D_10" { code { { @@ -38,7 +38,7 @@ object "D_10" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" + /// @use-src 0:"input.sol" object "D_10_deployed" { code { { diff --git a/test/cmdlineTests/ir_compiler_subobjects/err b/test/cmdlineTests/ir_compiler_subobjects/err index b300ec124361..66ebf4229caf 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/err +++ b/test/cmdlineTests/ir_compiler_subobjects/err @@ -1,5 +1,5 @@ Warning: Unused local variable. - --> ir_compiler_subobjects/input.sol:8:9: + --> input.sol:8:9: | 8 | C c = new C(); | ^^^ diff --git a/test/cmdlineTests/ir_compiler_subobjects/output b/test/cmdlineTests/ir_compiler_subobjects/output index 39ef53f5529b..08ee8bf5d0b5 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/output +++ b/test/cmdlineTests/ir_compiler_subobjects/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_compiler_subobjects/input.sol" +/// @use-src 0:"input.sol" object "C_3" { code { { @@ -12,7 +12,7 @@ object "C_3" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { @@ -25,7 +25,7 @@ object "C_3" { } Optimized IR: -/// @use-src 0:"ir_compiler_subobjects/input.sol" +/// @use-src 0:"input.sol" object "D_16" { code { { @@ -38,7 +38,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "D_16_deployed" { code { { @@ -76,7 +76,7 @@ object "D_16" { revert(0, 0) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3" { code { { @@ -89,7 +89,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { diff --git a/test/cmdlineTests/ir_optimized_transient_storage_value_type/output b/test/cmdlineTests/ir_optimized_transient_storage_value_type/output index 61d289e3f9e0..2f6918cabb36 100644 --- a/test/cmdlineTests/ir_optimized_transient_storage_value_type/output +++ b/test/cmdlineTests/ir_optimized_transient_storage_value_type/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_optimized_transient_storage_value_type/input.sol" +/// @use-src 0:"input.sol" object "C_14" { code { { @@ -11,7 +11,7 @@ object "C_14" { return(_1, _2) } } - /// @use-src 0:"ir_optimized_transient_storage_value_type/input.sol" + /// @use-src 0:"input.sol" object "C_14_deployed" { code { { diff --git a/test/cmdlineTests/ir_optimized_with_optimize/output b/test/cmdlineTests/ir_optimized_with_optimize/output index 8790e45d353d..bae07ea4eb05 100644 --- a/test/cmdlineTests/ir_optimized_with_optimize/output +++ b/test/cmdlineTests/ir_optimized_with_optimize/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_optimized_with_optimize/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { { @@ -11,7 +11,7 @@ object "C_2" { return(_1, _2) } } - /// @use-src 0:"ir_optimized_with_optimize/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" diff --git a/test/cmdlineTests/ir_subobject_order/output b/test/cmdlineTests/ir_subobject_order/output index da4390fff055..d41b65bf9a62 100644 --- a/test/cmdlineTests/ir_subobject_order/output +++ b/test/cmdlineTests/ir_subobject_order/output @@ -1,8 +1,8 @@ Optimized IR: -/// @use-src 0:"ir_subobject_order/input.sol" +/// @use-src 0:"input.sol" object "A_13" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "A_13_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" @@ -10,10 +10,10 @@ object "A_13" { } Optimized IR: -/// @use-src 0:"ir_subobject_order/input.sol" +/// @use-src 0:"input.sol" object "B_7" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "B_7_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" @@ -21,7 +21,7 @@ object "B_7" { } Optimized IR: -/// @use-src 0:"ir_subobject_order/input.sol" +/// @use-src 0:"input.sol" object "C_33" { code { { @@ -69,24 +69,24 @@ object "C_33" { return(_7, _8) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "C_33_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "A_13" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "A_13_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "B_7" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "B_7_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize/output b/test/cmdlineTests/ir_unoptimized_with_optimize/output index c5307123f0f5..b34558d2a49f 100644 --- a/test/cmdlineTests/ir_unoptimized_with_optimize/output +++ b/test/cmdlineTests/ir_unoptimized_with_optimize/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"ir_unoptimized_with_optimize/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { @@ -27,7 +27,7 @@ object "C_2" { } } - /// @use-src 0:"ir_unoptimized_with_optimize/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output index f5ecdd8bf5f0..b34558d2a49f 100644 --- a/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output +++ b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"ir_unoptimized_with_optimize_via_ir/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { @@ -27,7 +27,7 @@ object "C_2" { } } - /// @use-src 0:"ir_unoptimized_with_optimize_via_ir/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output index 5c822949a409..03f5564200bf 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_with_assembly_no_memoryguard_creation/input.sol" +/// @use-src 0:"input.sol" object "D_12" { code { { @@ -10,7 +10,7 @@ object "D_12" { return(128, _1) } } - /// @use-src 0:"ir_with_assembly_no_memoryguard_creation/input.sol" + /// @use-src 0:"input.sol" object "D_12_deployed" { code { { diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output index f6be1493ec79..9d07cd910e9f 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_with_assembly_no_memoryguard_runtime/input.sol" +/// @use-src 0:"input.sol" object "D_8" { code { { @@ -12,7 +12,7 @@ object "D_8" { return(_1, _2) } } - /// @use-src 0:"ir_with_assembly_no_memoryguard_runtime/input.sol" + /// @use-src 0:"input.sol" object "D_8_deployed" { code { { diff --git a/test/cmdlineTests/keccak_optimization_deploy_code/output b/test/cmdlineTests/keccak_optimization_deploy_code/output index 8b89ea5b6329..839e675210e7 100644 --- a/test/cmdlineTests/keccak_optimization_deploy_code/output +++ b/test/cmdlineTests/keccak_optimization_deploy_code/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"keccak_optimization_deploy_code/input.sol" +/// @use-src 0:"input.sol" object "C_12" { code { { @@ -14,7 +14,7 @@ object "C_12" { return(128, _1) } } - /// @use-src 0:"keccak_optimization_deploy_code/input.sol" + /// @use-src 0:"input.sol" object "C_12_deployed" { code { { diff --git a/test/cmdlineTests/keccak_optimization_low_runs/output b/test/cmdlineTests/keccak_optimization_low_runs/output index c308d737b2f5..328bdd59e621 100644 --- a/test/cmdlineTests/keccak_optimization_low_runs/output +++ b/test/cmdlineTests/keccak_optimization_low_runs/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"keccak_optimization_low_runs/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { { @@ -12,7 +12,7 @@ object "C_7" { return(_1, _2) } } - /// @use-src 0:"keccak_optimization_low_runs/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { { diff --git a/test/cmdlineTests/linking_qualified_library_name/args b/test/cmdlineTests/linking_qualified_library_name/args index dc996f46e236..e8a29e815367 100644 --- a/test/cmdlineTests/linking_qualified_library_name/args +++ b/test/cmdlineTests/linking_qualified_library_name/args @@ -1 +1 @@ -linking_qualified_library_name/contract1.sol --bin --libraries linking_qualified_library_name/math.sol:Log:0x7777777777777777777777777777777777777777 +contract1.sol --bin --libraries math.sol:Log:0x7777777777777777777777777777777777777777 diff --git a/test/cmdlineTests/linking_qualified_library_name/contract1.sol b/test/cmdlineTests/linking_qualified_library_name/contract1.sol index aedea65faaa7..d59420962939 100644 --- a/test/cmdlineTests/linking_qualified_library_name/contract1.sol +++ b/test/cmdlineTests/linking_qualified_library_name/contract1.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.0; -import "linking_qualified_library_name/math.sol"; +import "math.sol"; contract C { function foo() public { diff --git a/test/cmdlineTests/linking_qualified_library_name/output b/test/cmdlineTests/linking_qualified_library_name/output index 834874bf8e87..63359661bcd4 100644 --- a/test/cmdlineTests/linking_qualified_library_name/output +++ b/test/cmdlineTests/linking_qualified_library_name/output @@ -1,8 +1,8 @@ -======= linking_qualified_library_name/contract1.sol:C ======= +======= contract1.sol:C ======= Binary: -======= linking_qualified_library_name/math.sol:Log ======= +======= math.sol:Log ======= Binary: diff --git a/test/cmdlineTests/linking_solidity/args b/test/cmdlineTests/linking_solidity/args index 9a958527fd71..7689b925ae10 100644 --- a/test/cmdlineTests/linking_solidity/args +++ b/test/cmdlineTests/linking_solidity/args @@ -1 +1 @@ ---bin --bin-runtime --libraries linking_solidity/input.sol:L=0x1234567890123456789012345678901234567890 +--bin --bin-runtime --libraries input.sol:L=0x1234567890123456789012345678901234567890 diff --git a/test/cmdlineTests/linking_solidity/output b/test/cmdlineTests/linking_solidity/output index 307b131b5af3..ed60e0ccfc9b 100644 --- a/test/cmdlineTests/linking_solidity/output +++ b/test/cmdlineTests/linking_solidity/output @@ -1,11 +1,11 @@ -======= linking_solidity/input.sol:C ======= +======= input.sol:C ======= Binary: Binary of the runtime part: -======= linking_solidity/input.sol:L ======= +======= input.sol:L ======= Binary: Binary of the runtime part: diff --git a/test/cmdlineTests/linking_solidity_unresolved_references/args b/test/cmdlineTests/linking_solidity_unresolved_references/args index 8909b2779174..fbbed9f870b7 100644 --- a/test/cmdlineTests/linking_solidity_unresolved_references/args +++ b/test/cmdlineTests/linking_solidity_unresolved_references/args @@ -1 +1 @@ ---bin --bin-runtime --libraries linking_solidity_unresolved_references/input.sol:L1=0x1234567890123456789012345678901234567890 +--bin --bin-runtime --libraries input.sol:L1=0x1234567890123456789012345678901234567890 diff --git a/test/cmdlineTests/linking_solidity_unresolved_references/output b/test/cmdlineTests/linking_solidity_unresolved_references/output index f42191f51e0b..5df6611de091 100644 --- a/test/cmdlineTests/linking_solidity_unresolved_references/output +++ b/test/cmdlineTests/linking_solidity_unresolved_references/output @@ -1,23 +1,23 @@ -======= linking_solidity_unresolved_references/input.sol:C ======= +======= input.sol:C ======= Binary: -__$8ef13d1c56d5343bf69cf9444272079aa5$____$8ef13d1c56d5343bf69cf9444272079aa5$__ +__$a7fb54ac3bf4ba657d4a55d066b3521d62$____$a7fb54ac3bf4ba657d4a55d066b3521d62$__ -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 Binary of the runtime part: -__$8ef13d1c56d5343bf69cf9444272079aa5$____$8ef13d1c56d5343bf69cf9444272079aa5$__ +__$a7fb54ac3bf4ba657d4a55d066b3521d62$____$a7fb54ac3bf4ba657d4a55d066b3521d62$__ -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 -======= linking_solidity_unresolved_references/input.sol:L1 ======= +======= input.sol:L1 ======= Binary: Binary of the runtime part: -======= linking_solidity_unresolved_references/input.sol:L2 ======= +======= input.sol:L2 ======= Binary: Binary of the runtime part: diff --git a/test/cmdlineTests/linking_strict_assembly/output b/test/cmdlineTests/linking_strict_assembly/output index 4fa6edc0c372..756cc2822d3d 100644 --- a/test/cmdlineTests/linking_strict_assembly/output +++ b/test/cmdlineTests/linking_strict_assembly/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -16,11 +16,11 @@ Binary representation: 7312345678901234567890123456789012345678905f5500 Text representation: - /* "linking_strict_assembly/input.yul":58:93 */ + /* "input.yul":58:93 */ linkerSymbol("f919ba91ac99f96129544b80b9516b27a80e376b9dc693819d0b18b7e0395612") - /* "linking_strict_assembly/input.yul":113:114 */ + /* "input.yul":113:114 */ 0x00 - /* "linking_strict_assembly/input.yul":106:121 */ + /* "input.yul":106:121 */ sstore - /* "linking_strict_assembly/input.yul":22:137 */ + /* "input.yul":22:137 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output index e4fa4fcbd9ab..f347631001b9 100644 --- a/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_qualified_library_qualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output index ebf7f6542c52..d329296eb2c5 100644 --- a/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_qualified_library_unqualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output index 69c0a21f63c1..f4262400c815 100644 --- a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output +++ b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_same_library_name_different_files/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -18,19 +18,19 @@ Binary representation: 731111111111111111111111111111111111111111732222222222222222222222222222222222222222905f5560015500 Text representation: - /* "linking_strict_assembly_same_library_name_different_files/input.yul":59:89 */ + /* "input.yul":59:89 */ linkerSymbol("f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec") - /* "linking_strict_assembly_same_library_name_different_files/input.yul":115:145 */ + /* "input.yul":115:145 */ linkerSymbol("c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f") - /* "linking_strict_assembly_same_library_name_different_files/input.yul":158:174 */ + /* "input.yul":158:174 */ swap1 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":165:166 */ + /* "input.yul":165:166 */ 0x00 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":158:174 */ + /* "input.yul":158:174 */ sstore - /* "linking_strict_assembly_same_library_name_different_files/input.yul":194:195 */ + /* "input.yul":194:195 */ 0x01 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":187:203 */ + /* "input.yul":187:203 */ sstore - /* "linking_strict_assembly_same_library_name_different_files/input.yul":22:219 */ + /* "input.yul":22:219 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output index 14fafa4e4604..a6422d8fbce2 100644 --- a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output +++ b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -18,19 +18,19 @@ Binary representation: 73123456789012345678901234567890123456789073__$c3523432985587641d17c68161d2f700c5$__905f5560015500 Text representation: - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":59:89 */ + /* "input.yul":59:89 */ linkerSymbol("f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec") - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":115:145 */ + /* "input.yul":115:145 */ linkerSymbol("c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f") - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":158:174 */ + /* "input.yul":158:174 */ swap1 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":165:166 */ + /* "input.yul":165:166 */ 0x00 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":158:174 */ + /* "input.yul":158:174 */ sstore - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":194:195 */ + /* "input.yul":194:195 */ 0x01 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":187:203 */ + /* "input.yul":187:203 */ sstore - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":22:219 */ + /* "input.yul":22:219 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output index aaf03d0733b4..099b0ce54db3 100644 --- a/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_unqualified_library_qualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output index d91d89f5ca69..b4bb825435c3 100644 --- a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_unqualified_library_unqualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_unresolved_references/output b/test/cmdlineTests/linking_strict_assembly_unresolved_references/output index 3b2d84ab3c6b..7b45cae6eb61 100644 --- a/test/cmdlineTests/linking_strict_assembly_unresolved_references/output +++ b/test/cmdlineTests/linking_strict_assembly_unresolved_references/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_unresolved_references/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -18,19 +18,19 @@ Binary representation: 73123456789012345678901234567890123456789073__$fb58009a6b1ecea3b9d99bedd645df4ec3$__905f5560015500 Text representation: - /* "linking_strict_assembly_unresolved_references/input.yul":59:95 */ + /* "input.yul":59:95 */ linkerSymbol("05b0326038374a21e0895480a58bda0768cdcc04c8d18f154362d1ca5223d245") - /* "linking_strict_assembly_unresolved_references/input.yul":121:157 */ + /* "input.yul":121:157 */ linkerSymbol("fb58009a6b1ecea3b9d99bedd645df4ec308f17bc0087e5f39d078f77f809177") - /* "linking_strict_assembly_unresolved_references/input.yul":170:186 */ + /* "input.yul":170:186 */ swap1 - /* "linking_strict_assembly_unresolved_references/input.yul":177:178 */ + /* "input.yul":177:178 */ 0x00 - /* "linking_strict_assembly_unresolved_references/input.yul":170:186 */ + /* "input.yul":170:186 */ sstore - /* "linking_strict_assembly_unresolved_references/input.yul":206:207 */ + /* "input.yul":206:207 */ 0x01 - /* "linking_strict_assembly_unresolved_references/input.yul":199:215 */ + /* "input.yul":199:215 */ sstore - /* "linking_strict_assembly_unresolved_references/input.yul":22:231 */ + /* "input.yul":22:231 */ stop diff --git a/test/cmdlineTests/linking_unqualified_library_name/args b/test/cmdlineTests/linking_unqualified_library_name/args index 6118acf02caf..08f3b8cd1c06 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/args +++ b/test/cmdlineTests/linking_unqualified_library_name/args @@ -1 +1 @@ -linking_unqualified_library_name/contract1.sol linking_unqualified_library_name/contract2.sol --bin --libraries Log:0x7777777777777777777777777777777777777777 +contract1.sol contract2.sol --bin --libraries Log:0x7777777777777777777777777777777777777777 diff --git a/test/cmdlineTests/linking_unqualified_library_name/contract1.sol b/test/cmdlineTests/linking_unqualified_library_name/contract1.sol index 38e43f9d493e..893c63af07be 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/contract1.sol +++ b/test/cmdlineTests/linking_unqualified_library_name/contract1.sol @@ -2,7 +2,7 @@ pragma solidity >=0.0; -import "linking_unqualified_library_name/error.sol"; +import "error.sol"; contract C { function foo() public { diff --git a/test/cmdlineTests/linking_unqualified_library_name/contract2.sol b/test/cmdlineTests/linking_unqualified_library_name/contract2.sol index 6ddb8ad6e286..d59420962939 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/contract2.sol +++ b/test/cmdlineTests/linking_unqualified_library_name/contract2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.0; -import "linking_unqualified_library_name/math.sol"; +import "math.sol"; contract C { function foo() public { diff --git a/test/cmdlineTests/linking_unqualified_library_name/output b/test/cmdlineTests/linking_unqualified_library_name/output index be64a93c9bbc..68e254363fa1 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/output +++ b/test/cmdlineTests/linking_unqualified_library_name/output @@ -1,20 +1,20 @@ -======= linking_unqualified_library_name/contract1.sol:C ======= +======= contract1.sol:C ======= Binary: -__$cdf6d5ab08a9335b02e7c2475aa27d04fa$__ +__$4a937a7d3d68a205b3b2520e23ccff31ea$__ -// $cdf6d5ab08a9335b02e7c2475aa27d04fa$ -> linking_unqualified_library_name/error.sol:Log +// $4a937a7d3d68a205b3b2520e23ccff31ea$ -> error.sol:Log -======= linking_unqualified_library_name/contract2.sol:C ======= +======= contract2.sol:C ======= Binary: -__$22584241c2fc4f2884d5222245463779a8$__ +__$b77e1024bb5d89efefbab5fb1f7cb8fde7$__ -// $22584241c2fc4f2884d5222245463779a8$ -> linking_unqualified_library_name/math.sol:Log +// $b77e1024bb5d89efefbab5fb1f7cb8fde7$ -> math.sol:Log -======= linking_unqualified_library_name/error.sol:Log ======= +======= error.sol:Log ======= Binary: -======= linking_unqualified_library_name/math.sol:Log ======= +======= math.sol:Log ======= Binary: diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/err b/test/cmdlineTests/mcopy_bytes_array_abi_decode/err index de32e66295be..ead85d933e3a 100644 --- a/test/cmdlineTests/mcopy_bytes_array_abi_decode/err +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/err @@ -1,5 +1,5 @@ Warning: Statement has no effect. - --> mcopy_bytes_array_abi_decode/input.sol:7:9: + --> input.sol:7:9: | 7 | abi.decode("abcd", (bytes)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/output b/test/cmdlineTests/mcopy_bytes_array_abi_decode/output index 2a24ec834fa1..806094f76a15 100644 --- a/test/cmdlineTests/mcopy_bytes_array_abi_decode/output +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"mcopy_bytes_array_abi_decode/input.sol" +/// @use-src 0:"input.sol" object "C_15" { code { @@ -27,7 +27,7 @@ object "C_15" { } } - /// @use-src 0:"mcopy_bytes_array_abi_decode/input.sol" + /// @use-src 0:"input.sol" object "C_15_deployed" { code { diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output index 170cdf1a7a3a..f3cd766954c5 100644 --- a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"mcopy_bytes_array_returned_from_function/input.sol" +/// @use-src 0:"input.sol" object "C_14" { code { { @@ -11,7 +11,7 @@ object "C_14" { return(_1, _2) } } - /// @use-src 0:"mcopy_bytes_array_returned_from_function/input.sol" + /// @use-src 0:"input.sol" object "C_14_deployed" { code { { diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/output b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output index 548c34de8628..3adeae0f58e6 100644 --- a/test/cmdlineTests/mcopy_string_literal_returned_from_function/output +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"mcopy_string_literal_returned_from_function/input.sol" +/// @use-src 0:"input.sol" object "C_10" { code { { @@ -11,7 +11,7 @@ object "C_10" { return(_1, _2) } } - /// @use-src 0:"mcopy_string_literal_returned_from_function/input.sol" + /// @use-src 0:"input.sol" object "C_10_deployed" { code { { diff --git a/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output index 842580597d12..1ea3bdf20209 100644 --- a/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output +++ b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"memoryguard_shadowing_by_inline_assembly_identifiers/input.sol" +/// @use-src 0:"input.sol" object "C_10" { code { @@ -27,7 +27,7 @@ object "C_10" { } } - /// @use-src 0:"memoryguard_shadowing_by_inline_assembly_identifiers/input.sol" + /// @use-src 0:"input.sol" object "C_10_deployed" { code { diff --git a/test/cmdlineTests/message_format/err b/test/cmdlineTests/message_format/err index eee8267e25f3..1bb6a6469273 100644 --- a/test/cmdlineTests/message_format/err +++ b/test/cmdlineTests/message_format/err @@ -1,50 +1,50 @@ Warning: Source file does not specify required compiler version! ---> message_format/input.sol +--> input.sol Warning: Unused local variable. - --> message_format/input.sol:9:27: + --> input.sol:9:27: | 9 | function f() public { int x; } | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:10:27: + --> input.sol:10:27: | 10 | function g() public { int x; } | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:99:14: + --> input.sol:99:14: | 99 | /**/ int a; /**/ | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:100:14: + --> input.sol:100:14: | 100 | /**/ int b; /**/ | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:101:14: + --> input.sol:101:14: | 101 | /**/ int c; /**/ | ^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format/input.sol:9:5: + --> input.sol:9:5: | 9 | function f() public { int x; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format/input.sol:10:5: + --> input.sol:10:5: | 10 | function g() public { int x; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format/input.sol:11:5: + --> input.sol:11:5: | 11 | function h() public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/message_format_utf8/err b/test/cmdlineTests/message_format_utf8/err index 58d45127cb3d..e14a048fc54b 100644 --- a/test/cmdlineTests/message_format_utf8/err +++ b/test/cmdlineTests/message_format_utf8/err @@ -1,29 +1,29 @@ Warning: Statement has no effect. - --> message_format_utf8/input.sol:5:51: + --> input.sol:5:51: | 5 | /* ©©©©ᄅ©©©©© 2017 */ constructor () { unicode"©©©©ᄅ©©©©©" ; } | ^^^^^^^^^^^^^^^^^^^ Warning: Statement has no effect. - --> message_format_utf8/input.sol:9:25: + --> input.sol:9:25: | 9 | unicode"S = π × r²"; | ^^^^^^^^^^^^^^^^^^^ Warning: Statement has no effect. - --> message_format_utf8/input.sol:10:39: + --> input.sol:10:39: | 10 | /* ₀₁₂₃₄⁵⁶⁷⁸⁹ */ unicode"∑ 1/n! ≈ 2.7"; // tabs in-between | ^^^^^^^^^^^^^^^^^^^^^ Warning: Statement has no effect. - --> message_format_utf8/input.sol:11:30: + --> input.sol:11:30: | 11 | /* Ŀŏŗėɯ ïƥŝʉɱ */ unicode"μὴ χεῖρον βέλτιστον"; // tabs in-between and inside | ^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format_utf8/input.sol:15:2: + --> input.sol:15:2: | 15 | function selector() public returns(uint) { // starts with tab | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/metadata/output b/test/cmdlineTests/metadata/output index b6a684b844f3..0910128894df 100644 --- a/test/cmdlineTests/metadata/output +++ b/test/cmdlineTests/metadata/output @@ -1,4 +1,4 @@ -======= metadata/input.sol:C ======= +======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"metadata/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"metadata/input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} diff --git a/test/cmdlineTests/model_checker_bmc_loop_iterations/err b/test/cmdlineTests/model_checker_bmc_loop_iterations/err index cbb2b0f9daca..0ec7a09b6d3c 100644 --- a/test/cmdlineTests/model_checker_bmc_loop_iterations/err +++ b/test/cmdlineTests/model_checker_bmc_loop_iterations/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_bmc_loop_iterations/input.sol:10:3: + --> input.sol:10:3: | 10 | assert(x == 3); | ^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err b/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err index 1bd45b6c6f57..4b1a2ea3b1fd 100644 --- a/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err +++ b/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err @@ -1 +1 @@ -Error: the argument ('model_checker_bmc_loop_iterations_no_argument/input.sol') for option '--model-checker-bmc-loop-iterations' is invalid +Error: the argument ('input.sol') for option '--model-checker-bmc-loop-iterations' is invalid diff --git a/test/cmdlineTests/model_checker_contracts_all/err b/test/cmdlineTests/model_checker_contracts_all/err index 9135483d5f79..0d19af174c39 100644 --- a/test/cmdlineTests/model_checker_contracts_all/err +++ b/test/cmdlineTests/model_checker_contracts_all/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: B.constructor() B.f(0) - --> model_checker_contracts_all/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ y = 0 Transaction trace: A.constructor() A.g(0) - --> model_checker_contracts_all/input.sol:10:9: + --> input.sol:10:9: | 10 | assert(y > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_contracts_all_explicit/args b/test/cmdlineTests/model_checker_contracts_all_explicit/args index 6e6bee97aed8..151a636fe265 100644 --- a/test/cmdlineTests/model_checker_contracts_all_explicit/args +++ b/test/cmdlineTests/model_checker_contracts_all_explicit/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_all_explicit/input.sol:B,model_checker_contracts_all_explicit/input.sol:A +--model-checker-engine all --model-checker-contracts input.sol:B,input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_all_explicit/err b/test/cmdlineTests/model_checker_contracts_all_explicit/err index 003c0dffe018..25ce2e5e9947 100644 --- a/test/cmdlineTests/model_checker_contracts_all_explicit/err +++ b/test/cmdlineTests/model_checker_contracts_all_explicit/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: B.constructor() B.f(0) - --> model_checker_contracts_all_explicit/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ y = 0 Transaction trace: A.constructor() A.g(0) - --> model_checker_contracts_all_explicit/input.sol:10:3: + --> input.sol:10:3: | 10 | assert(y > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_contract/args b/test/cmdlineTests/model_checker_contracts_inexistent_contract/args index b3c44af85b87..1128064d8a59 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_contract/args +++ b/test/cmdlineTests/model_checker_contracts_inexistent_contract/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_inexistent_contract/input.sol:C +--model-checker-engine all --model-checker-contracts input.sol:C diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err index 6326537e928c..72f613bf3ccd 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err +++ b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err @@ -1 +1 @@ -Warning: Requested contract "C" does not exist in source "model_checker_contracts_inexistent_contract/input.sol". +Warning: Requested contract "C" does not exist in source "input.sol". diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_source/args b/test/cmdlineTests/model_checker_contracts_inexistent_source/args index 6d91ecc34355..b98256bf4e9b 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_source/args +++ b/test/cmdlineTests/model_checker_contracts_inexistent_source/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_inexistent_source/A.sol:A +--model-checker-engine all --model-checker-contracts A.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_source/err b/test/cmdlineTests/model_checker_contracts_inexistent_source/err index 218588ad83d2..3c93482595f5 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_source/err +++ b/test/cmdlineTests/model_checker_contracts_inexistent_source/err @@ -1 +1 @@ -Warning: Requested source "model_checker_contracts_inexistent_source/A.sol" does not exist. +Warning: Requested source "A.sol" does not exist. diff --git a/test/cmdlineTests/model_checker_contracts_one_contract_missing/args b/test/cmdlineTests/model_checker_contracts_one_contract_missing/args index 7ea3d3f04610..8670db9b57a9 100644 --- a/test/cmdlineTests/model_checker_contracts_one_contract_missing/args +++ b/test/cmdlineTests/model_checker_contracts_one_contract_missing/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_all_explicit/input.sol:,model_checker_contracts_all_explicit/input.sol:A +--model-checker-engine all --model-checker-contracts input.sol:,input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_one_contract_missing/err b/test/cmdlineTests/model_checker_contracts_one_contract_missing/err index d4e93bcd705e..88e675624e2f 100644 --- a/test/cmdlineTests/model_checker_contracts_one_contract_missing/err +++ b/test/cmdlineTests/model_checker_contracts_one_contract_missing/err @@ -1 +1 @@ -Error: Invalid option for --model-checker-contracts: model_checker_contracts_all_explicit/input.sol:,model_checker_contracts_all_explicit/input.sol:A +Error: Invalid option for --model-checker-contracts: input.sol:,input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_only_one/args b/test/cmdlineTests/model_checker_contracts_only_one/args index ae76a81d6735..ff3ad9e1d4fe 100644 --- a/test/cmdlineTests/model_checker_contracts_only_one/args +++ b/test/cmdlineTests/model_checker_contracts_only_one/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_only_one/input.sol:A +--model-checker-engine all --model-checker-contracts input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_only_one/err b/test/cmdlineTests/model_checker_contracts_only_one/err index 9c8ade6931c3..4472abefaf32 100644 --- a/test/cmdlineTests/model_checker_contracts_only_one/err +++ b/test/cmdlineTests/model_checker_contracts_only_one/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: A.constructor() B.f(0) - --> model_checker_contracts_only_one/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ y = 0 Transaction trace: A.constructor() A.g(0) - --> model_checker_contracts_only_one/input.sol:10:3: + --> input.sol:10:3: | 10 | assert(y > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_engine_all/err b/test/cmdlineTests/model_checker_engine_all/err index 12614fd55f82..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_engine_all/err +++ b/test/cmdlineTests/model_checker_engine_all/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_engine_all/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_engine_bmc/err b/test/cmdlineTests/model_checker_engine_bmc/err index ed46539d6510..dcedef48bf09 100644 --- a/test/cmdlineTests/model_checker_engine_bmc/err +++ b/test/cmdlineTests/model_checker_engine_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_engine_bmc/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_engine_chc/err b/test/cmdlineTests/model_checker_engine_chc/err index 95198fa2027a..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_engine_chc/err +++ b/test/cmdlineTests/model_checker_engine_chc/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_engine_chc/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err b/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err index e9c2d70a9739..58be5002f2d1 100644 --- a/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err +++ b/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_ext_calls_trusted_chc/input.sol:5:2: + --> input.sol:5:2: | 5 | function f() public view returns (uint) { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err b/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err index b06333e43bd5..73b355510e2f 100644 --- a/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err +++ b/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() test.g(0) e.f() -- untrusted external call - --> model_checker_ext_calls_untrusted_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x == 0); | ^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err index dcef00b5fd0e..b47334040b61 100644 --- a/test/cmdlineTests/model_checker_invariants_all/err +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -1,8 +1,8 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (true || !(x >= 1)) -Reentrancy property(ies) for model_checker_invariants_all/input.sol:test: +Reentrancy property(ies) for input.sol:test: ((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract/err b/test/cmdlineTests/model_checker_invariants_contract/err index 3ecad6b35d48..2ea993088670 100644 --- a/test/cmdlineTests/model_checker_invariants_contract/err +++ b/test/cmdlineTests/model_checker_invariants_contract/err @@ -1,4 +1,4 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_contract/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (true || !(x >= 1)) diff --git a/test/cmdlineTests/model_checker_invariants_contract_eld/err b/test/cmdlineTests/model_checker_invariants_contract_eld/err index 29c5a5bc8eae..4dc823ec8880 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_eld/err +++ b/test/cmdlineTests/model_checker_invariants_contract_eld/err @@ -1,4 +1,4 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_contract_eld/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (x = 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err index 7764e89abc59..b47334040b61 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err @@ -1,8 +1,8 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_contract_reentrancy/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (true || !(x >= 1)) -Reentrancy property(ies) for model_checker_invariants_contract_reentrancy/input.sol:test: +Reentrancy property(ies) for input.sol:test: ((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/err b/test/cmdlineTests/model_checker_invariants_reentrancy/err index 8891b0e18c59..42ac3ca73311 100644 --- a/test/cmdlineTests/model_checker_invariants_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/err @@ -1,6 +1,6 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Reentrancy property(ies) for model_checker_invariants_reentrancy/input.sol:test: +Info: Reentrancy property(ies) for input.sol:test: ((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err b/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err index b896b21bc7f9..730e43b9588e 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_default_all_engines/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err b/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err index f4a2d33e053b..7146c519260c 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_default_bmc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err b/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err index ab73c6bf56cd..730e43b9588e 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_default_chc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err b/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err index 297eb497a34d..d45cd29d3f6d 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err @@ -1,17 +1,17 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_true_all_engines/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_all_engines/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x >= 0); | ^^^^^^^^^^^^^^ Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_all_engines/input.sol:6:9: + --> input.sol:6:9: | 6 | assert(x < 1000); | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err b/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err index bcec557f61ae..6bcf720faef7 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err @@ -1,17 +1,17 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_true_bmc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). Info: BMC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_bmc/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x >= 0); | ^^^^^^^^^^^^^^ Info: BMC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_bmc/input.sol:6:9: + --> input.sol:6:9: | 6 | assert(x < 1000); | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err b/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err index fc14f494676f..d45cd29d3f6d 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err @@ -1,17 +1,17 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_true_chc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_chc/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x >= 0); | ^^^^^^^^^^^^^^ Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_chc/input.sol:6:9: + --> input.sol:6:9: | 6 | assert(x < 1000); | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err b/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err index 7a338f614952..18f317ac8c85 100644 --- a/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err +++ b/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err @@ -1,5 +1,5 @@ Warning: CHC: Assertion violation might happen here. - --> model_checker_show_unproved_true_all_engines/input.sol:10:9: + --> input.sol:10:9: | 10 | assert(s.x > 0); | ^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unproved_true_chc/err b/test/cmdlineTests/model_checker_show_unproved_true_chc/err index 8274f4b463f2..e68e08677316 100644 --- a/test/cmdlineTests/model_checker_show_unproved_true_chc/err +++ b/test/cmdlineTests/model_checker_show_unproved_true_chc/err @@ -1,5 +1,5 @@ Warning: CHC: Assertion violation might happen here. - --> model_checker_show_unproved_true_chc/input.sol:10:9: + --> input.sol:10:9: | 10 | assert(s.x > 0); | ^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err b/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err index 53c664ffc764..681a5995649d 100644 --- a/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err +++ b/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err @@ -1,5 +1,5 @@ Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives). - --> model_checker_show_unsupported_true_all_engines/input.sol:5:9: + --> input.sol:5:9: | 5 | assembly {} | ^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err b/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err index 013a7b0f118c..681a5995649d 100644 --- a/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err +++ b/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err @@ -1,5 +1,5 @@ Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives). - --> model_checker_show_unsupported_true_bmc/input.sol:5:9: + --> input.sol:5:9: | 5 | assembly {} | ^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unsupported_true_chc/err b/test/cmdlineTests/model_checker_show_unsupported_true_chc/err index 8dad0cc65bce..681a5995649d 100644 --- a/test/cmdlineTests/model_checker_show_unsupported_true_chc/err +++ b/test/cmdlineTests/model_checker_show_unsupported_true_chc/err @@ -1,5 +1,5 @@ Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives). - --> model_checker_show_unsupported_true_chc/input.sol:5:9: + --> input.sol:5:9: | 5 | assembly {} | ^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_cvc5/err b/test/cmdlineTests/model_checker_solvers_cvc5/err index 1c36b103a65d..dcedef48bf09 100644 --- a/test/cmdlineTests/model_checker_solvers_cvc5/err +++ b/test/cmdlineTests/model_checker_solvers_cvc5/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_solvers_cvc5/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_cvc5_eld/err b/test/cmdlineTests/model_checker_solvers_cvc5_eld/err index 81a9f3a56342..b2cb662706f2 100644 --- a/test/cmdlineTests/model_checker_solvers_cvc5_eld/err +++ b/test/cmdlineTests/model_checker_solvers_cvc5_eld/err @@ -1,7 +1,7 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Warning: BMC: Condition is always false. - --> model_checker_solvers_cvc5_eld/input.sol:6:7: + --> input.sol:6:7: | 6 | if (y == 0) | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_eld/err b/test/cmdlineTests/model_checker_solvers_eld/err index ff7ad37b313e..460764a0e997 100644 --- a/test/cmdlineTests/model_checker_solvers_eld/err +++ b/test/cmdlineTests/model_checker_solvers_eld/err @@ -1,5 +1,5 @@ Warning: CHC: Assertion violation happens here. - --> model_checker_solvers_eld/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_z3/err b/test/cmdlineTests/model_checker_solvers_z3/err index 67349d8e17fe..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_solvers_z3/err +++ b/test/cmdlineTests/model_checker_solvers_z3/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_solvers_z3/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_z3_implicit/err b/test/cmdlineTests/model_checker_solvers_z3_implicit/err index 98d61828d9c1..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_solvers_z3_implicit/err +++ b/test/cmdlineTests/model_checker_solvers_z3_implicit/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_solvers_z3_implicit/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err b/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err index 5699afcdeb3a..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err +++ b/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_solvers_z3_smtlib2/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_all_all_engines/err b/test/cmdlineTests/model_checker_targets_all_all_engines/err index c67d97b61216..e095ba263c5a 100644 --- a/test/cmdlineTests/model_checker_targets_all_all_engines/err +++ b/test/cmdlineTests/model_checker_targets_all_all_engines/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_all_all_engines/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_all_all_engines/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -83,7 +83,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ @@ -91,7 +91,7 @@ test.f(0x0, 1) Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Warning: BMC: Condition is always true. - --> model_checker_targets_all_all_engines/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_all_bmc/err b/test/cmdlineTests/model_checker_targets_all_bmc/err index 27a51a67bd63..3887cc6b2a7f 100644 --- a/test/cmdlineTests/model_checker_targets_all_bmc/err +++ b/test/cmdlineTests/model_checker_targets_all_bmc/err @@ -1,12 +1,12 @@ Warning: BMC: Condition is always true. - --> model_checker_targets_all_bmc/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ Note: Callstack: Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_all_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -19,7 +19,7 @@ Note: Callstack: Note: Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_all_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ Note: Callstack: Note: Warning: BMC: Division by zero happens here. - --> model_checker_targets_all_bmc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -45,7 +45,7 @@ Note: Callstack: Note: Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_all_bmc/input.sol:10:3: + --> input.sol:10:3: | 10 | a.transfer(x); | ^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ Note: Callstack: Note: Warning: BMC: Assertion violation happens here. - --> model_checker_targets_all_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_all_chc/err b/test/cmdlineTests/model_checker_targets_all_chc/err index 9c257cefe9eb..c3853983af72 100644 --- a/test/cmdlineTests/model_checker_targets_all_chc/err +++ b/test/cmdlineTests/model_checker_targets_all_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_all_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_all_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -83,7 +83,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_assert_bmc/err b/test/cmdlineTests/model_checker_targets_assert_bmc/err index 90486bf792d9..27395c9dc507 100644 --- a/test/cmdlineTests/model_checker_targets_assert_bmc/err +++ b/test/cmdlineTests/model_checker_targets_assert_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_targets_assert_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_assert_chc/err b/test/cmdlineTests/model_checker_targets_assert_chc/err index 1bf48bfa9abb..ada7c3d3dc90 100644 --- a/test/cmdlineTests/model_checker_targets_assert_chc/err +++ b/test/cmdlineTests/model_checker_targets_assert_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_assert_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_balance_bmc/err b/test/cmdlineTests/model_checker_targets_balance_bmc/err index 39a8aac56df7..178bd66620bd 100644 --- a/test/cmdlineTests/model_checker_targets_balance_bmc/err +++ b/test/cmdlineTests/model_checker_targets_balance_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_balance_bmc/input.sol:10:3: + --> input.sol:10:3: | 10 | a.transfer(x); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err b/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err index 6a376dd7ea5b..a7228dd768e8 100644 --- a/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err +++ b/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Condition is always true. - --> model_checker_targets_constant_condition_bmc/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_default_all_engines/err b/test/cmdlineTests/model_checker_targets_default_all_engines/err index 62d3b203cb9c..58cbc01f1436 100644 --- a/test/cmdlineTests/model_checker_targets_default_all_engines/err +++ b/test/cmdlineTests/model_checker_targets_default_all_engines/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ @@ -61,7 +61,7 @@ test.f(0x0, 1) Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Warning: BMC: Condition is always true. - --> model_checker_targets_default_all_engines/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_default_bmc/err b/test/cmdlineTests/model_checker_targets_default_bmc/err index 1122be36b061..bc85e3cb4acc 100644 --- a/test/cmdlineTests/model_checker_targets_default_bmc/err +++ b/test/cmdlineTests/model_checker_targets_default_bmc/err @@ -1,12 +1,12 @@ Warning: BMC: Condition is always true. - --> model_checker_targets_default_bmc/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ Note: Callstack: Warning: BMC: Division by zero happens here. - --> model_checker_targets_default_bmc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -19,7 +19,7 @@ Note: Callstack: Note: Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_default_bmc/input.sol:10:3: + --> input.sol:10:3: | 10 | a.transfer(x); | ^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ Note: Callstack: Note: Warning: BMC: Assertion violation happens here. - --> model_checker_targets_default_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_default_chc/err b/test/cmdlineTests/model_checker_targets_default_chc/err index 70f3c5bc6072..e8b7382168ac 100644 --- a/test/cmdlineTests/model_checker_targets_default_chc/err +++ b/test/cmdlineTests/model_checker_targets_default_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err b/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err index bcf2c0c83a18..2d554ebceb7d 100644 --- a/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err +++ b/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Division by zero happens here. - --> model_checker_targets_div_by_zero_bmc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err b/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err index 3156dd90bd3f..81616b3bedab 100644 --- a/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err +++ b/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_div_by_zero_chc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err b/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err index b4426a80e351..907a19f1e11a 100644 --- a/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err +++ b/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_out_of_bounds_chc/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_overflow_bmc/err b/test/cmdlineTests/model_checker_targets_overflow_bmc/err index f2f475c304e8..a0f9ff1e07a9 100644 --- a/test/cmdlineTests/model_checker_targets_overflow_bmc/err +++ b/test/cmdlineTests/model_checker_targets_overflow_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_overflow_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_overflow_chc/err b/test/cmdlineTests/model_checker_targets_overflow_chc/err index e7f98ff4dc7a..60298f02285a 100644 --- a/test/cmdlineTests/model_checker_targets_overflow_chc/err +++ b/test/cmdlineTests/model_checker_targets_overflow_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_overflow_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_pop_empty_chc/err b/test/cmdlineTests/model_checker_targets_pop_empty_chc/err index d3478a700420..a01248775704 100644 --- a/test/cmdlineTests/model_checker_targets_pop_empty_chc/err +++ b/test/cmdlineTests/model_checker_targets_pop_empty_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_pop_empty_chc/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_bmc/err b/test/cmdlineTests/model_checker_targets_underflow_bmc/err index 2162bec3aac9..db14639238c6 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_bmc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_underflow_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_chc/err b/test/cmdlineTests/model_checker_targets_underflow_chc/err index 448b0e25ca7c..57c6649a40f4 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_chc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_underflow_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err index 9712b8cb7614..670b064ce183 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_underflow_overflow_assert_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -12,7 +12,7 @@ Note: Callstack: Note: Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_underflow_overflow_assert_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ Note: Callstack: Note: Warning: BMC: Assertion violation happens here. - --> model_checker_targets_underflow_overflow_assert_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err index a0fbbe61a543..4602e76006dc 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_underflow_overflow_assert_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_underflow_overflow_assert_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_underflow_overflow_assert_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err index f3675ac5acbe..ea6dfb99cb5d 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_underflow_overflow_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -12,7 +12,7 @@ Note: Callstack: Note: Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_underflow_overflow_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err index 0dcfb1c254a3..8eed85ac3de3 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_underflow_overflow_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_underflow_overflow_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index 04abaf600103..8eeff65b91a6 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"name_simplifier/input.sol" +/// @use-src 0:"input.sol" object "C_59" { code { { @@ -12,7 +12,7 @@ object "C_59" { return(_1, _2) } } - /// @use-src 0:"name_simplifier/input.sol" + /// @use-src 0:"input.sol" object "C_59_deployed" { code { { diff --git a/test/cmdlineTests/no_cbor_metadata/output b/test/cmdlineTests/no_cbor_metadata/output index 0328ece3f27c..295bc228bf1e 100644 --- a/test/cmdlineTests/no_cbor_metadata/output +++ b/test/cmdlineTests/no_cbor_metadata/output @@ -1,4 +1,4 @@ -======= no_cbor_metadata/input.sol:C ======= +======= input.sol:C ======= Binary: 608080604052346013576003908160188239f35b5f80fdfe5f80fd diff --git a/test/cmdlineTests/no_contract_combined_json/output b/test/cmdlineTests/no_contract_combined_json/output index 8c454e341442..a408cbdbc957 100644 --- a/test/cmdlineTests/no_contract_combined_json/output +++ b/test/cmdlineTests/no_contract_combined_json/output @@ -1,11 +1,11 @@ { "sourceList": [ - "no_contract_combined_json/input.sol" + "input.sol" ], "sources": { - "no_contract_combined_json/input.sol": { + "input.sol": { "AST": { - "absolutePath": "no_contract_combined_json/input.sol", + "absolutePath": "input.sol", "exportedSymbols": {}, "id": 2, "license": "GPL-3.0", diff --git a/test/cmdlineTests/no_import_callback/args b/test/cmdlineTests/no_import_callback/args index e816120d0db6..7efc6a77b677 100644 --- a/test/cmdlineTests/no_import_callback/args +++ b/test/cmdlineTests/no_import_callback/args @@ -1 +1 @@ ---no-import-callback no_import_callback/contract_1.sol +--no-import-callback contract_1.sol diff --git a/test/cmdlineTests/no_import_callback/err b/test/cmdlineTests/no_import_callback/err index 45690e34c8f2..c4e6d5701e22 100644 --- a/test/cmdlineTests/no_import_callback/err +++ b/test/cmdlineTests/no_import_callback/err @@ -1,5 +1,5 @@ Error: Source "contract_2.sol" not found: No import callback. - --> no_import_callback/contract_1.sol:4:1: + --> contract_1.sol:4:1: | 4 | import "contract_2.sol"; | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/object_compiler/output b/test/cmdlineTests/object_compiler/output index a88851b96c71..b552b3f241d5 100644 --- a/test/cmdlineTests/object_compiler/output +++ b/test/cmdlineTests/object_compiler/output @@ -1,5 +1,5 @@ -======= object_compiler/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "MyContract" { @@ -26,40 +26,40 @@ Binary representation: 335f55600880600d5f395ff3fe5f545f5260205ff3 Text representation: - /* "object_compiler/input.yul":65:73 */ + /* "input.yul":65:73 */ caller - /* "object_compiler/input.yul":62:63 */ + /* "input.yul":62:63 */ 0x00 - /* "object_compiler/input.yul":55:74 */ + /* "input.yul":55:74 */ sstore - /* "object_compiler/input.yul":97:116 */ + /* "input.yul":97:116 */ dataSize(sub_0) - /* "object_compiler/input.yul":141:162 */ + /* "input.yul":141:162 */ dup1 dataOffset(sub_0) - /* "object_compiler/input.yul":138:139 */ + /* "input.yul":138:139 */ 0x00 - /* "object_compiler/input.yul":129:167 */ + /* "input.yul":129:167 */ codecopy - /* "object_compiler/input.yul":187:188 */ + /* "input.yul":187:188 */ 0x00 - /* "object_compiler/input.yul":180:193 */ + /* "input.yul":180:193 */ return stop sub_0: assembly { - /* "object_compiler/input.yul":294:295 */ + /* "input.yul":294:295 */ 0x00 - /* "object_compiler/input.yul":288:296 */ + /* "input.yul":288:296 */ sload - /* "object_compiler/input.yul":285:286 */ + /* "input.yul":285:286 */ 0x00 - /* "object_compiler/input.yul":278:297 */ + /* "input.yul":278:297 */ mstore - /* "object_compiler/input.yul":324:328 */ + /* "input.yul":324:328 */ 0x20 - /* "object_compiler/input.yul":321:322 */ + /* "input.yul":321:322 */ 0x00 - /* "object_compiler/input.yul":314:329 */ + /* "input.yul":314:329 */ return } diff --git a/test/cmdlineTests/optimize_full_storage_write/output b/test/cmdlineTests/optimize_full_storage_write/output index 9ebec71f0320..53e00008b08a 100644 --- a/test/cmdlineTests/optimize_full_storage_write/output +++ b/test/cmdlineTests/optimize_full_storage_write/output @@ -1,7 +1,7 @@ -======= optimize_full_storage_write/input.sol:OptimizeFullSlotWrite ======= +======= input.sol:OptimizeFullSlotWrite ======= EVM assembly: - /* "optimize_full_storage_write/input.sol":60:213 contract OptimizeFullSlotWrite {... */ + /* "input.sol":60:213 contract OptimizeFullSlotWrite {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimize_full_storage_write/input.sol":60:213 contract OptimizeFullSlotWrite {... */ + /* "input.sol":60:213 contract OptimizeFullSlotWrite {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,16 +40,16 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimize_full_storage_write/input.sol":111:211 function f() public {... */ + /* "input.sol":111:211 function f() public {... */ tag_3: tag_4 - /* "optimize_full_storage_write/input.sol":192:207 nums[3] = 44444 */ + /* "input.sol":192:207 nums[3] = 44444 */ 0xad9c000000000000823500000000000056ce0000000000002b67 - /* "optimize_full_storage_write/input.sol":135:139 nums */ + /* "input.sol":135:139 nums */ 0x00 - /* "optimize_full_storage_write/input.sol":192:207 nums[3] = 44444 */ + /* "input.sol":192:207 nums[3] = 44444 */ sstore - /* "optimize_full_storage_write/input.sol":111:211 function f() public {... */ + /* "input.sol":111:211 function f() public {... */ jump tag_4: stop diff --git a/test/cmdlineTests/optimizer_BlockDeDuplicator/err b/test/cmdlineTests/optimizer_BlockDeDuplicator/err index e29fc4fc3fd7..9d851c2acd29 100644 --- a/test/cmdlineTests/optimizer_BlockDeDuplicator/err +++ b/test/cmdlineTests/optimizer_BlockDeDuplicator/err @@ -1,11 +1,11 @@ Warning: Statement has no effect. - --> optimizer_BlockDeDuplicator/input.sol:7:27: + --> input.sol:7:27: | 7 | function f() public { true ? 1 : 3;} | ^^^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> optimizer_BlockDeDuplicator/input.sol:7:5: + --> input.sol:7:5: | 7 | function f() public { true ? 1 : 3;} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/optimizer_BlockDeDuplicator/output b/test/cmdlineTests/optimizer_BlockDeDuplicator/output index fb72e4bc1ee8..b3a645be3569 100644 --- a/test/cmdlineTests/optimizer_BlockDeDuplicator/output +++ b/test/cmdlineTests/optimizer_BlockDeDuplicator/output @@ -1,23 +1,23 @@ -======= optimizer_BlockDeDuplicator/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ mstore(0x40, 0x80) - /* "optimizer_BlockDeDuplicator/input.sol":179:210 function() r = true ? fun_x : f */ + /* "input.sol":179:210 function() r = true ? fun_x : f */ 0x00 dup1 sload not(sub(shl(0x40, 0x01), 0x01)) and - /* "optimizer_BlockDeDuplicator/input.sol":201:206 fun_x */ + /* "input.sol":201:206 fun_x */ or(tag_0_7, shl(0x20, tag_2)) sub(shl(0x40, 0x01), 0x01) - /* "optimizer_BlockDeDuplicator/input.sol":179:210 function() r = true ? fun_x : f */ + /* "input.sol":179:210 function() r = true ? fun_x : f */ and or swap1 sstore - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ callvalue dup1 iszero @@ -27,10 +27,10 @@ EVM assembly: tag_5: pop jump(tag_6) - /* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */ + /* "input.sol":138:174 function f() public { true ? 1 : 3;} */ tag_2: jump // out - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ tag_6: dataSize(sub_0) dup1 @@ -42,7 +42,7 @@ tag_6: stop sub_0: assembly { - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -71,7 +71,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */ + /* "input.sol":138:174 function f() public { true ? 1 : 3;} */ tag_3: stop tag_7: diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index c1e0796f56fa..a16ac43a0fda 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"optimizer_array_sload/input.sol" +/// @use-src 0:"input.sol" object "Arraysum_34" { code { { @@ -12,7 +12,7 @@ object "Arraysum_34" { return(_1, _2) } } - /// @use-src 0:"optimizer_array_sload/input.sol" + /// @use-src 0:"input.sol" object "Arraysum_34_deployed" { code { { diff --git a/test/cmdlineTests/optimizer_inliner_add/output b/test/cmdlineTests/optimizer_inliner_add/output index 9ebc9977daab..e4076c2fbc62 100644 --- a/test/cmdlineTests/optimizer_inliner_add/output +++ b/test/cmdlineTests/optimizer_inliner_add/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_add/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_add/input.sol":165:305 contract C {... */ + /* "input.sol":165:305 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_add/input.sol":165:305 contract C {... */ + /* "input.sol":165:305 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_add/input.sol":182:303 function f() public pure {... */ + /* "input.sol":182:303 function f() public pure {... */ tag_3: tag_4 tag_5 @@ -48,32 +48,32 @@ sub_0: assembly { tag_4: stop tag_5: - /* "optimizer_inliner_add/input.sol":221:227 uint x */ + /* "input.sol":221:227 uint x */ 0x00 - /* "optimizer_inliner_add/input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ + /* "input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ tag_7: - /* "optimizer_inliner_add/input.sol":237:239 10 */ + /* "input.sol":237:239 10 */ 0x0a - /* "optimizer_inliner_add/input.sol":233:234 x */ + /* "input.sol":233:234 x */ dup2 - /* "optimizer_inliner_add/input.sol":233:239 x < 10 */ + /* "input.sol":233:239 x < 10 */ lt - /* "optimizer_inliner_add/input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ + /* "input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ iszero tag_8 jumpi - /* "optimizer_inliner_add/input.sol":149:154 x + y */ + /* "input.sol":149:154 x + y */ dup1 add - /* "optimizer_inliner_add/input.sol":273:274 1 */ + /* "input.sol":273:274 1 */ 0x01 - /* "optimizer_inliner_add/input.sol":149:154 x + y */ + /* "input.sol":149:154 x + y */ add - /* "optimizer_inliner_add/input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ + /* "input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ jump(tag_7) tag_8: pop - /* "optimizer_inliner_add/input.sol":182:303 function f() public pure {... */ + /* "input.sol":182:303 function f() public pure {... */ jump // out auxdata: diff --git a/test/cmdlineTests/optimizer_inliner_call_from_constructor/output b/test/cmdlineTests/optimizer_inliner_call_from_constructor/output index f42f9de094c6..8c7b544bbdd6 100644 --- a/test/cmdlineTests/optimizer_inliner_call_from_constructor/output +++ b/test/cmdlineTests/optimizer_inliner_call_from_constructor/output @@ -1,9 +1,9 @@ -======= optimizer_inliner_call_from_constructor/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_call_from_constructor/input.sol":60:263 contract C {... */ + /* "input.sol":60:263 contract C {... */ mstore(0x40, 0x80) - /* "optimizer_inliner_call_from_constructor/input.sol":89:115 constructor() { x = a(); } */ + /* "input.sol":89:115 constructor() { x = a(); } */ callvalue dup1 iszero @@ -12,13 +12,13 @@ EVM assembly: revert(0x00, 0x00) tag_1: pop - /* "optimizer_inliner_call_from_constructor/input.sol":257:258 6 */ + /* "input.sol":257:258 6 */ 0x06 - /* "optimizer_inliner_call_from_constructor/input.sol":105:106 x */ + /* "input.sol":105:106 x */ 0x00 - /* "optimizer_inliner_call_from_constructor/input.sol":105:112 x = a() */ + /* "input.sol":105:112 x = a() */ sstore - /* "optimizer_inliner_call_from_constructor/input.sol":60:263 contract C {... */ + /* "input.sol":60:263 contract C {... */ dataSize(sub_0) dup1 dataOffset(sub_0) @@ -29,7 +29,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_call_from_constructor/input.sol":60:263 contract C {... */ + /* "input.sol":60:263 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -48,11 +48,11 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_call_from_constructor/input.sol":120:175 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":120:175 function a() public pure returns (uint) { return f(); } */ tag_3: - /* "optimizer_inliner_call_from_constructor/input.sol":257:258 6 */ + /* "input.sol":257:258 6 */ 0x06 - /* "optimizer_inliner_call_from_constructor/input.sol":120:175 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":120:175 function a() public pure returns (uint) { return f(); } */ mload(0x40) /* "#utility.yul":160:185 */ swap1 @@ -62,7 +62,7 @@ sub_0: assembly { 0x20 /* "#utility.yul":133:151 */ add - /* "optimizer_inliner_call_from_constructor/input.sol":120:175 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":120:175 function a() public pure returns (uint) { return f(); } */ mload(0x40) dup1 swap2 diff --git a/test/cmdlineTests/optimizer_inliner_dynamic_reference/output b/test/cmdlineTests/optimizer_inliner_dynamic_reference/output index b1c5c74d9037..5313893fc735 100644 --- a/test/cmdlineTests/optimizer_inliner_dynamic_reference/output +++ b/test/cmdlineTests/optimizer_inliner_dynamic_reference/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_dynamic_reference/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_dynamic_reference/input.sol":60:367 contract C {... */ + /* "input.sol":60:367 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_dynamic_reference/input.sol":60:367 contract C {... */ + /* "input.sol":60:367 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -50,11 +50,11 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ tag_3: - /* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */ + /* "input.sol":361:362 6 */ 0x06 - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ tag_6: mload(0x40) /* "#utility.yul":160:185 */ @@ -65,78 +65,78 @@ sub_0: assembly { 0x20 /* "#utility.yul":133:151 */ add - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ mload(0x40) dup1 swap2 sub swap1 return - /* "optimizer_inliner_dynamic_reference/input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ tag_4: tag_6 tag_11 jump // in - /* "optimizer_inliner_dynamic_reference/input.sol":125:155 function g() public { x = f; } */ + /* "input.sol":125:155 function g() public { x = f; } */ tag_5: - /* "optimizer_inliner_dynamic_reference/input.sol":147:148 x */ + /* "input.sol":147:148 x */ 0x00 - /* "optimizer_inliner_dynamic_reference/input.sol":147:152 x = f */ + /* "input.sol":147:152 x = f */ dup1 sload not(0xffffffffffffffff) and - /* "optimizer_inliner_dynamic_reference/input.sol":151:152 f */ + /* "input.sol":151:152 f */ tag_17 - /* "optimizer_inliner_dynamic_reference/input.sol":147:152 x = f */ + /* "input.sol":147:152 x = f */ or swap1 sstore - /* "optimizer_inliner_dynamic_reference/input.sol":125:155 function g() public { x = f; } */ + /* "input.sol":125:155 function g() public { x = f; } */ stop - /* "optimizer_inliner_dynamic_reference/input.sol":209:212 f() */ + /* "input.sol":209:212 f() */ tag_16: - /* "optimizer_inliner_dynamic_reference/input.sol":202:212 return f() */ + /* "input.sol":202:212 return f() */ swap1 pop - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ swap1 jump // out - /* "optimizer_inliner_dynamic_reference/input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ tag_11: - /* "optimizer_inliner_dynamic_reference/input.sol":280:284 uint */ + /* "input.sol":280:284 uint */ 0x00 - /* "optimizer_inliner_dynamic_reference/input.sol":295:296 x */ + /* "input.sol":295:296 x */ dup1 sload - /* "optimizer_inliner_dynamic_reference/input.sol":295:298 x() */ + /* "input.sol":295:298 x() */ tag_19 swap1 - /* "optimizer_inliner_dynamic_reference/input.sol":295:296 x */ + /* "input.sol":295:296 x */ dup1 iszero tag_20 mul or - /* "optimizer_inliner_dynamic_reference/input.sol":295:298 x() */ + /* "input.sol":295:298 x() */ 0xffffffff and jump // in tag_19: - /* "optimizer_inliner_dynamic_reference/input.sol":295:302 x() + 1 */ + /* "input.sol":295:302 x() + 1 */ tag_16 swap1 - /* "optimizer_inliner_dynamic_reference/input.sol":301:302 1 */ + /* "input.sol":301:302 1 */ 0x01 - /* "optimizer_inliner_dynamic_reference/input.sol":295:302 x() + 1 */ + /* "input.sol":295:302 x() + 1 */ tag_22 jump // in - /* "optimizer_inliner_dynamic_reference/input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ tag_17: - /* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */ + /* "input.sol":361:362 6 */ 0x06 swap1 - /* "optimizer_inliner_dynamic_reference/input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ jump // out tag_20: tag_25 diff --git a/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output b/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output index 24ecaede0787..5997bd1c7b60 100644 --- a/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output +++ b/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output @@ -1,9 +1,9 @@ -======= optimizer_inliner_dynamic_reference_constructor/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ mstore(0x40, 0x80) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":77:101 constructor() { x = f; } */ + /* "input.sol":77:101 constructor() { x = f; } */ callvalue dup1 iszero @@ -12,31 +12,31 @@ EVM assembly: revert(0x00, 0x00) tag_1: pop - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":93:94 x */ + /* "input.sol":93:94 x */ 0x00 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":93:98 x = f */ + /* "input.sol":93:98 x = f */ dup1 sload not(sub(shl(0x40, 0x01), 0x01)) and - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":97:98 f */ + /* "input.sol":97:98 f */ or(tag_0_12, shl(0x20, tag_4)) sub(shl(0x40, 0x01), 0x01) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":93:98 x = f */ + /* "input.sol":93:98 x = f */ and or swap1 sstore - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ jump(tag_5) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ tag_4: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */ + /* "input.sol":355:356 6 */ 0x06 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ jump // out - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ tag_5: dataSize(sub_0) dup1 @@ -48,7 +48,7 @@ tag_5: stop sub_0: assembly { - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -72,11 +72,11 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ tag_3: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */ + /* "input.sol":355:356 6 */ 0x06 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ tag_5: mload(0x40) /* "#utility.yul":160:185 */ @@ -87,61 +87,61 @@ sub_0: assembly { 0x20 /* "#utility.yul":133:151 */ add - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ mload(0x40) dup1 swap2 sub swap1 return - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ tag_4: tag_5 tag_10 jump // in - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":203:206 f() */ + /* "input.sol":203:206 f() */ tag_14: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":196:206 return f() */ + /* "input.sol":196:206 return f() */ swap1 pop - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ swap1 jump // out - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ tag_10: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":274:278 uint */ + /* "input.sol":274:278 uint */ 0x00 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:290 x */ + /* "input.sol":289:290 x */ dup1 sload - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:292 x() */ + /* "input.sol":289:292 x() */ tag_16 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:290 x */ + /* "input.sol":289:290 x */ dup1 iszero tag_17 mul or - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:292 x() */ + /* "input.sol":289:292 x() */ 0xffffffff and jump // in tag_16: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:296 x() + 1 */ + /* "input.sol":289:296 x() + 1 */ tag_14 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":295:296 1 */ + /* "input.sol":295:296 1 */ 0x01 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:296 x() + 1 */ + /* "input.sol":289:296 x() + 1 */ tag_19 jump // in - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ tag_12: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */ + /* "input.sol":355:356 6 */ 0x06 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ jump // out tag_17: tag_21 diff --git a/test/cmdlineTests/optimizer_inliner_inc/output b/test/cmdlineTests/optimizer_inliner_inc/output index 3a3639e190a5..d634bf2d431b 100644 --- a/test/cmdlineTests/optimizer_inliner_inc/output +++ b/test/cmdlineTests/optimizer_inliner_inc/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_inc/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_inc/input.sol":157:279 contract C {... */ + /* "input.sol":157:279 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_inc/input.sol":157:279 contract C {... */ + /* "input.sol":157:279 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_inc/input.sol":174:277 function f() public pure {... */ + /* "input.sol":174:277 function f() public pure {... */ tag_3: tag_4 tag_5 @@ -48,29 +48,29 @@ sub_0: assembly { tag_4: stop tag_5: - /* "optimizer_inliner_inc/input.sol":213:219 uint x */ + /* "input.sol":213:219 uint x */ 0x00 - /* "optimizer_inliner_inc/input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ + /* "input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ tag_7: - /* "optimizer_inliner_inc/input.sol":229:231 10 */ + /* "input.sol":229:231 10 */ 0x0a - /* "optimizer_inliner_inc/input.sol":225:226 x */ + /* "input.sol":225:226 x */ dup2 - /* "optimizer_inliner_inc/input.sol":225:231 x < 10 */ + /* "input.sol":225:231 x < 10 */ lt - /* "optimizer_inliner_inc/input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ + /* "input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ iszero tag_8 jumpi - /* "optimizer_inliner_inc/input.sol":145:146 1 */ + /* "input.sol":145:146 1 */ 0x01 - /* "optimizer_inliner_inc/input.sol":141:146 x + 1 */ + /* "input.sol":141:146 x + 1 */ add - /* "optimizer_inliner_inc/input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ + /* "input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ jump(tag_7) tag_8: pop - /* "optimizer_inliner_inc/input.sol":174:277 function f() public pure {... */ + /* "input.sol":174:277 function f() public pure {... */ jump // out auxdata: diff --git a/test/cmdlineTests/optimizer_inliner_multireturn/output b/test/cmdlineTests/optimizer_inliner_multireturn/output index 46d74055a208..20de1c219961 100644 --- a/test/cmdlineTests/optimizer_inliner_multireturn/output +++ b/test/cmdlineTests/optimizer_inliner_multireturn/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_multireturn/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_multireturn/input.sol":162:298 contract C {... */ + /* "input.sol":162:298 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_multireturn/input.sol":162:298 contract C {... */ + /* "input.sol":162:298 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_multireturn/input.sol":179:296 function f() public pure {... */ + /* "input.sol":179:296 function f() public pure {... */ tag_3: tag_4 tag_5 @@ -48,35 +48,35 @@ sub_0: assembly { tag_4: stop tag_5: - /* "optimizer_inliner_multireturn/input.sol":219:225 uint x */ + /* "input.sol":219:225 uint x */ 0x00 - /* "optimizer_inliner_multireturn/input.sol":241:242 1 */ + /* "input.sol":241:242 1 */ 0x01 - /* "optimizer_inliner_multireturn/input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ + /* "input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ tag_7: - /* "optimizer_inliner_multireturn/input.sol":249:251 10 */ + /* "input.sol":249:251 10 */ 0x0a - /* "optimizer_inliner_multireturn/input.sol":245:246 x */ + /* "input.sol":245:246 x */ dup3 - /* "optimizer_inliner_multireturn/input.sol":245:251 x < 10 */ + /* "input.sol":245:251 x < 10 */ lt - /* "optimizer_inliner_multireturn/input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ + /* "input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ iszero tag_8 jumpi pop - /* "optimizer_inliner_multireturn/input.sol":146:147 1 */ + /* "input.sol":146:147 1 */ 0x01 - /* "optimizer_inliner_multireturn/input.sol":142:147 x + 1 */ + /* "input.sol":142:147 x + 1 */ dup2 add swap1 - /* "optimizer_inliner_multireturn/input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ + /* "input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ jump(tag_7) tag_8: pop pop - /* "optimizer_inliner_multireturn/input.sol":179:296 function f() public pure {... */ + /* "input.sol":179:296 function f() public pure {... */ jump // out auxdata: diff --git a/test/cmdlineTests/optimizer_user_yul/output b/test/cmdlineTests/optimizer_user_yul/output index c106c011b37c..b18e155bf947 100644 --- a/test/cmdlineTests/optimizer_user_yul/output +++ b/test/cmdlineTests/optimizer_user_yul/output @@ -1,71 +1,71 @@ -======= optimizer_user_yul/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_user_yul/input.sol":60:518 contract C... */ + /* "input.sol":60:518 contract C... */ mstore(0x40, 0x80) - /* "optimizer_user_yul/input.sol":101:106 int a */ + /* "input.sol":101:106 int a */ 0x00 - /* "optimizer_user_yul/input.sol":181:190 let x,y,z */ + /* "input.sol":181:190 let x,y,z */ 0x00 0x00 0x00 - /* "optimizer_user_yul/input.sol":205:206 1 */ + /* "input.sol":205:206 1 */ 0x01 - /* "optimizer_user_yul/input.sol":202:203 0 */ + /* "input.sol":202:203 0 */ 0x00 - /* "optimizer_user_yul/input.sol":195:207 sstore(0, 1) */ + /* "input.sol":195:207 sstore(0, 1) */ sstore - /* "optimizer_user_yul/input.sol":212:258 for { } sload(4) { } {... */ + /* "input.sol":212:258 for { } sload(4) { } {... */ tag_3: - /* "optimizer_user_yul/input.sol":226:227 4 */ + /* "input.sol":226:227 4 */ 0x04 - /* "optimizer_user_yul/input.sol":220:228 sload(4) */ + /* "input.sol":220:228 sload(4) */ sload - /* "optimizer_user_yul/input.sol":212:258 for { } sload(4) { } {... */ + /* "input.sol":212:258 for { } sload(4) { } {... */ iszero tag_5 jumpi pop - /* "optimizer_user_yul/input.sol":244:253 exp(x, y) */ + /* "input.sol":244:253 exp(x, y) */ dup1 dup3 exp - /* "optimizer_user_yul/input.sol":212:258 for { } sload(4) { } {... */ + /* "input.sol":212:258 for { } sload(4) { } {... */ jump(tag_3) tag_5: - /* "optimizer_user_yul/input.sol":216:219 { } */ + /* "input.sol":216:219 { } */ pop pop pop - /* "optimizer_user_yul/input.sol":268:269 2 */ + /* "input.sol":268:269 2 */ 0x02 - /* "optimizer_user_yul/input.sol":263:269 a := 2 */ + /* "input.sol":263:269 a := 2 */ swap1 pop - /* "optimizer_user_yul/input.sol":369:370 3 */ + /* "input.sol":369:370 3 */ 0x03 - /* "optimizer_user_yul/input.sol":366:367 2 */ + /* "input.sol":366:367 2 */ 0x02 - /* "optimizer_user_yul/input.sol":359:371 sstore(2, 3) */ + /* "input.sol":359:371 sstore(2, 3) */ sstore - /* "optimizer_user_yul/input.sol":390:391 5 */ + /* "input.sol":390:391 5 */ 0x05 - /* "optimizer_user_yul/input.sol":384:392 sload(5) */ + /* "input.sol":384:392 sload(5) */ sload iszero - /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ + /* "input.sol":376:509 for { } sload(5) { } {... */ tag_6: - /* "optimizer_user_yul/input.sol":384:392 sload(5) */ + /* "input.sol":384:392 sload(5) */ dup1 - /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ + /* "input.sol":376:509 for { } sload(5) { } {... */ iszero tag_6 jumpi - /* "optimizer_user_yul/input.sol":380:383 { } */ + /* "input.sol":380:383 { } */ pop - /* "optimizer_user_yul/input.sol":340:513 {... */ + /* "input.sol":340:513 {... */ pop - /* "optimizer_user_yul/input.sol":60:518 contract C... */ + /* "input.sol":60:518 contract C... */ dataSize(sub_0) dup1 dataOffset(sub_0) @@ -76,7 +76,7 @@ tag_6: stop sub_0: assembly { - /* "optimizer_user_yul/input.sol":60:518 contract C... */ + /* "input.sol":60:518 contract C... */ mstore(0x40, 0x80) revert(0x00, 0x00) diff --git a/test/cmdlineTests/require_overload/err b/test/cmdlineTests/require_overload/err index 184c8c22bdd0..c267269fe43b 100644 --- a/test/cmdlineTests/require_overload/err +++ b/test/cmdlineTests/require_overload/err @@ -1,5 +1,5 @@ Error: No matching declaration found after argument-dependent lookup. - --> require_overload/input.sol:5:9: + --> input.sol:5:9: | 5 | require(this); | ^^^^^^^ diff --git a/test/cmdlineTests/require_with_error_ir/output b/test/cmdlineTests/require_with_error_ir/output index 09515f3cd82e..236931eea4cf 100644 --- a/test/cmdlineTests/require_with_error_ir/output +++ b/test/cmdlineTests/require_with_error_ir/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"require_with_error_ir/input.sol" +/// @use-src 0:"input.sol" object "C_36" { code { @@ -27,7 +27,7 @@ object "C_36" { } } - /// @use-src 0:"require_with_error_ir/input.sol" + /// @use-src 0:"input.sol" object "C_36_deployed" { code { diff --git a/test/cmdlineTests/require_with_string_ir/output b/test/cmdlineTests/require_with_string_ir/output index 3a19db372796..9b0bd869fe3b 100644 --- a/test/cmdlineTests/require_with_string_ir/output +++ b/test/cmdlineTests/require_with_string_ir/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"require_with_string_ir/input.sol" +/// @use-src 0:"input.sol" object "C_28" { code { @@ -27,7 +27,7 @@ object "C_28" { } } - /// @use-src 0:"require_with_string_ir/input.sol" + /// @use-src 0:"input.sol" object "C_28_deployed" { code { diff --git a/test/cmdlineTests/revert_strings/output b/test/cmdlineTests/revert_strings/output index 0f16ff9d0f8f..1fdb4b884c2d 100644 --- a/test/cmdlineTests/revert_strings/output +++ b/test/cmdlineTests/revert_strings/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"revert_strings/input.sol" +/// @use-src 0:"input.sol" object "C_15" { code { /// @src 0:59:147 "contract C {..." @@ -46,7 +46,7 @@ object "C_15" { /// @src 0:59:147 "contract C {..." } - /// @use-src 0:"revert_strings/input.sol" + /// @use-src 0:"input.sol" object "C_15_deployed" { code { /// @src 0:59:147 "contract C {..." diff --git a/test/cmdlineTests/stack_too_deep_from_code_transform/err b/test/cmdlineTests/stack_too_deep_from_code_transform/err index 588f4d437945..8820cce05aff 100644 --- a/test/cmdlineTests/stack_too_deep_from_code_transform/err +++ b/test/cmdlineTests/stack_too_deep_from_code_transform/err @@ -1,6 +1,6 @@ Error: Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ] memoryguard was present. - --> stack_too_deep_from_code_transform/input.sol:1:1: + --> input.sol:1:1: | 1 | contract C { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json index 3059e1ecd3e3..14dec3178f24 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_all/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": ["*"]}, diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json index 8e338322b0c7..f2311603a09f 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_location_only/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": ["location"]}, diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json index c9184d944bfd..09386f2bef3d 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_none/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": []}, diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json index 962688913096..cb6ac84463ee 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_snippet_only/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": ["snippet"]}, diff --git a/test/cmdlineTests/standard_irOptimized_ast_requested/input.json b/test/cmdlineTests/standard_irOptimized_ast_requested/input.json index fd16983068aa..23f17f4ae40d 100644 --- a/test/cmdlineTests/standard_irOptimized_ast_requested/input.json +++ b/test/cmdlineTests/standard_irOptimized_ast_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_irOptimized_ast_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": {"*": {"*": ["irOptimizedAst"]}} diff --git a/test/cmdlineTests/standard_ir_ast_requested/input.json b/test/cmdlineTests/standard_ir_ast_requested/input.json index 1cb1083a2ef6..07cfc13edee7 100644 --- a/test/cmdlineTests/standard_ir_ast_requested/input.json +++ b/test/cmdlineTests/standard_ir_ast_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_ir_ast_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": {"*": {"*": ["irAst"]}} diff --git a/test/cmdlineTests/standard_metadata/input.json b/test/cmdlineTests/standard_metadata/input.json index ae4bfe8f5965..8ca8da20a260 100644 --- a/test/cmdlineTests/standard_metadata/input.json +++ b/test/cmdlineTests/standard_metadata/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_metadata/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json b/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json index 5d65bb2e2269..52c0b9c7ac82 100644 --- a/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json +++ b/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_invalid_detail_type/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"details": {"peephole": 7}} diff --git a/test/cmdlineTests/standard_optimizer_invalid_details/input.json b/test/cmdlineTests/standard_optimizer_invalid_details/input.json index dbab578d6175..b6c590b5e87a 100644 --- a/test/cmdlineTests/standard_optimizer_invalid_details/input.json +++ b/test/cmdlineTests/standard_optimizer_invalid_details/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_invalid_details/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"details": {"notThere": true}} diff --git a/test/cmdlineTests/standard_optimizer_no_yul/input.json b/test/cmdlineTests/standard_optimizer_no_yul/input.json index 42ab767be632..ad1199dcf318 100644 --- a/test/cmdlineTests/standard_optimizer_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yul/input.json b/test/cmdlineTests/standard_optimizer_yul/input.json index cf40ef970bbb..7d27780e54c1 100644 --- a/test/cmdlineTests/standard_optimizer_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails/input.json b/test/cmdlineTests/standard_optimizer_yulDetails/input.json index 6cdf504fd854..53f1981d492a 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json index 4aba68350fb6..d132a4797ed2 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_no_object/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json index 584b8bf83e42..dca784c63fd6 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json index 48de0cce3f51..ebdf48e3a478 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json index 5be769f7676a..a93f21739315 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json index 0bddd9d9dc23..4caee0761778 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json index 2baf7a7235fc..bddd8d531ff4 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_nested_brackets/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json index 1c055d91545e..08aba5ccc7f0 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json index 511860250476..586560917fa0 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json index e6f2abaa2847..0166a4248ee3 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_type/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json index e3cd50027b17..554bfe2e5797 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json index 6cf7a233479c..aa4b172bbd0d 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json index b557a9662d8e..c3dde4dd3bbe 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json index 7d2f529ccf7f..c293911639f2 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json index 9c603d6f7f0b..8c4801da597a 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json index 5780bea83aa8..9d126b88ee4f 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json index 8e6add377cac..aecf8d9d5c1e 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json index 321ac8e99ab8..1396b4269ab5 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json index abd8cc0c8bac..8ccf21992999 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_without_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"details": {"yulDetails": 7} diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json index b640f033dc46..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_analysis_error_fatal/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json index 0214e00e8406..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_analysis_error_fatal_after_current_step/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json b/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json index 904ebc5bf287..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_analysis_error_non_fatal/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/input.json b/test/cmdlineTests/standard_outputs_on_compilation_error/input.json index 855f007689b8..0555ba5e93f9 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/input.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_compilation_error/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"enabled": true}, diff --git a/test/cmdlineTests/standard_outputs_on_parsing_error/input.json b/test/cmdlineTests/standard_outputs_on_parsing_error/input.json index a0d00c4e9e39..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_parsing_error/input.json +++ b/test/cmdlineTests/standard_outputs_on_parsing_error/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_parsing_error/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json index a01e842b384d..dc86ac68494e 100644 --- a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "in.sol": {"urls": ["standard_stack_too_deep_from_code_transform/in.sol"]} + "in.sol": {"urls": ["in.sol"]} }, "settings": { "viaIR": true, diff --git a/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json b/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json index 34f157495034..c09db6a6ed84 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json +++ b/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_stop_after_parsing_ast_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "stopAfter": "parsing", diff --git a/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json b/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json index 7ef3d37fd305..274ca87c44e4 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json +++ b/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_stop_after_parsing_bytecode_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "stopAfter": "parsing", diff --git a/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json b/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json index ac4d623c7103..597468e20432 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json +++ b/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_stop_after_parsing_non_binary_output_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "stopAfter": "parsing", diff --git a/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json b/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json index 4d2aea1f147a..ecb97bef2c3a 100644 --- a/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json +++ b/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_undeployable_contract_all_outputs/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_urls_existing_and_missing/input.json b/test/cmdlineTests/standard_urls_existing_and_missing/input.json index 686e8128eca2..575145836b39 100644 --- a/test/cmdlineTests/standard_urls_existing_and_missing/input.json +++ b/test/cmdlineTests/standard_urls_existing_and_missing/input.json @@ -3,9 +3,9 @@ "sources": { "url_not_found.sol": { "urls": [ - "standard_urls_existing_and_missing/non-existent-contract-1.sol", - "standard_urls_existing_and_missing/contract.sol", - "standard_urls_existing_and_missing/non-existent-contract-2.sol" + "non-existent-contract-1.sol", + "contract.sol", + "non-existent-contract-2.sol" ] } }, diff --git a/test/cmdlineTests/standard_urls_existing_and_missing/output.json b/test/cmdlineTests/standard_urls_existing_and_missing/output.json index e9db1135d764..4204cdb45b99 100644 --- a/test/cmdlineTests/standard_urls_existing_and_missing/output.json +++ b/test/cmdlineTests/standard_urls_existing_and_missing/output.json @@ -2,8 +2,8 @@ "errors": [ { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_existing_and_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_existing_and_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", "severity": "warning", "type": "Warning" } diff --git a/test/cmdlineTests/standard_urls_missing/input.json b/test/cmdlineTests/standard_urls_missing/input.json index fecc50eb03a6..5ba6e71619c6 100644 --- a/test/cmdlineTests/standard_urls_missing/input.json +++ b/test/cmdlineTests/standard_urls_missing/input.json @@ -3,9 +3,9 @@ "sources": { "url_not_found.sol": { "urls": [ - "standard_urls_missing/non-existent-contract-1.sol", - "standard_urls_missing/non-existent-contract.sol", - "standard_urls_missing/non-existent-contract-2.sol" + "non-existent-contract-1.sol", + "non-existent-contract.sol", + "non-existent-contract-2.sol" ] } }, diff --git a/test/cmdlineTests/standard_urls_missing/output.json b/test/cmdlineTests/standard_urls_missing/output.json index 7e2bb3dd59c2..8f766b055718 100644 --- a/test/cmdlineTests/standard_urls_missing/output.json +++ b/test/cmdlineTests/standard_urls_missing/output.json @@ -2,22 +2,22 @@ "errors": [ { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", "severity": "error", "type": "IOError" }, { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_missing/non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_missing/non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", "severity": "error", "type": "IOError" }, { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_missing/non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_missing/non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", "severity": "error", "type": "IOError" } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/input.json b/test/cmdlineTests/standard_yul_cfg_json_export/input.json index aee56abf8600..b5353721ee09 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/input.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_yul_cfg_json_export/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_yul_code_generation_error/input.json b/test/cmdlineTests/standard_yul_code_generation_error/input.json index 905eef6c758a..0f4da43fc66d 100644 --- a/test/cmdlineTests/standard_yul_code_generation_error/input.json +++ b/test/cmdlineTests/standard_yul_code_generation_error/input.json @@ -1,6 +1,6 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_code_generation_error/in.yul"]} + "C": {"urls": ["in.yul"]} } } diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json index 3e5b81c5ef69..e52867fa329d 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json @@ -3,7 +3,7 @@ "sources": { "C": { "urls": [ - "standard_yul_debug_info_ethdebug_compatible_output/in.yul" + "in.yul" ] } }, diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json index f05e6f361aca..c2c501c96616 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json @@ -3,7 +3,7 @@ "sources": { "C": { "urls": [ - "standard_yul_debug_info_ethdebug_incompatible_output/in.yul" + "in.yul" ] } }, diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json index be4fbb64fce3..16ef6ef33f74 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json @@ -3,7 +3,7 @@ "sources": { "C": { "urls": [ - "standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul" + "in.yul" ] } }, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_all/input.json b/test/cmdlineTests/standard_yul_debug_info_print_all/input.json index 1e6ed81a43a5..705c9ba7cc41 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_all/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_all/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": ["*"]}, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json b/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json index 867bc6e705ff..84ad0edadf18 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_location_only/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": ["location"]}, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_none/input.json b/test/cmdlineTests/standard_yul_debug_info_print_none/input.json index 705cf3879e4e..13681dd8b114 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_none/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_none/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_none/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": []}, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json b/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json index ee247218f33e..ed74c075288f 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_snippet_only/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": ["snippet"]}, diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json index 83acd4c42085..652620bedd51 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_assign_immutable/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json index abfb7ee863af..67c5fedc7fd0 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_bytecode_ir/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json index 54094c67305f..17949761f0f2 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_bytecode_iroptimized/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json index e222dfeda8c2..5c5e9c5f76e1 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_deployed_bytecode/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json index 20779012030d..655def5c1abf 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_deployed_bytecode/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json index 3153a378db84..67c5fedc7fd0 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_ir/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json index 180abcf31f8d..b08c9dcd7286 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_iroptimize/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json index 9f0c8b0d5cef..d7aec1f0889c 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_optimize_ir/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json index 81b637abd5b5..eeabdbcb9845 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_optimize_iroptimized/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/stop_after_parsing_ast/output b/test/cmdlineTests/stop_after_parsing_ast/output index 6cca9557da1b..e6d54c42615c 100644 --- a/test/cmdlineTests/stop_after_parsing_ast/output +++ b/test/cmdlineTests/stop_after_parsing_ast/output @@ -1,9 +1,9 @@ JSON AST (compact format): -======= stop_after_parsing_ast/input.sol ======= +======= input.sol ======= { - "absolutePath": "stop_after_parsing_ast/input.sol", + "absolutePath": "input.sol", "id": 4, "license": "GPL-3.0", "nodeType": "SourceUnit", diff --git a/test/cmdlineTests/storage_layout_transient_value_types/input.json b/test/cmdlineTests/storage_layout_transient_value_types/input.json index 8c90a7dde233..7a12ca85c985 100644 --- a/test/cmdlineTests/storage_layout_transient_value_types/input.json +++ b/test/cmdlineTests/storage_layout_transient_value_types/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["storage_layout_transient_value_types/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/storage_layout_user_defined/err b/test/cmdlineTests/storage_layout_user_defined/err index a9b5f07b19a0..e3815925acb9 100644 --- a/test/cmdlineTests/storage_layout_user_defined/err +++ b/test/cmdlineTests/storage_layout_user_defined/err @@ -1,2 +1,2 @@ Warning: Source file does not specify required compiler version! ---> storage_layout_user_defined/input.sol +--> input.sol diff --git a/test/cmdlineTests/storage_layout_user_defined/output b/test/cmdlineTests/storage_layout_user_defined/output index bb7819c66f12..d5be033ffe45 100644 --- a/test/cmdlineTests/storage_layout_user_defined/output +++ b/test/cmdlineTests/storage_layout_user_defined/output @@ -1,11 +1,11 @@ -======= storage_layout_user_defined/input.sol:C ======= +======= input.sol:C ======= Contract Storage Layout: { "storage": [ { "astId": 7, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "a", "offset": 0, "slot": "0", @@ -13,7 +13,7 @@ Contract Storage Layout: }, { "astId": 10, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "b", "offset": 16, "slot": "0", @@ -21,7 +21,7 @@ Contract Storage Layout: }, { "astId": 13, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "c", "offset": 0, "slot": "1", @@ -29,7 +29,7 @@ Contract Storage Layout: }, { "astId": 16, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "d", "offset": 16, "slot": "1", @@ -37,7 +37,7 @@ Contract Storage Layout: }, { "astId": 19, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "e", "offset": 17, "slot": "1", @@ -45,7 +45,7 @@ Contract Storage Layout: }, { "astId": 22, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "f", "offset": 18, "slot": "1", @@ -53,7 +53,7 @@ Contract Storage Layout: }, { "astId": 25, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "g", "offset": 19, "slot": "1", @@ -61,7 +61,7 @@ Contract Storage Layout: }, { "astId": 28, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "h", "offset": 20, "slot": "1", diff --git a/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output b/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output index 1be4da0b6ee9..54276e472651 100644 --- a/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output +++ b/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output @@ -1,4 +1,4 @@ -======= storage_layout_user_defined_no_pretty_print/input.sol:C ======= +======= input.sol:C ======= Contract Storage Layout: {"storage":[]} diff --git a/test/cmdlineTests/strict_asm_ast_compact_json/output b/test/cmdlineTests/strict_asm_ast_compact_json/output index b2271c36cb05..1099f0c12a37 100644 --- a/test/cmdlineTests/strict_asm_ast_compact_json/output +++ b/test/cmdlineTests/strict_asm_ast_compact_json/output @@ -1,5 +1,5 @@ -======= strict_asm_ast_compact_json/input.yul (EVM) ======= +======= input.yul (EVM) ======= AST: { diff --git a/test/cmdlineTests/strict_asm_debug_info_print_all/output b/test/cmdlineTests/strict_asm_debug_info_print_all/output index 0e58baf578e6..ea8afb6a2f06 100644 --- a/test/cmdlineTests/strict_asm_debug_info_print_all/output +++ b/test/cmdlineTests/strict_asm_debug_info_print_all/output @@ -1,5 +1,5 @@ -======= strict_asm_debug_info_print_all/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: /// @use-src 0:"input.sol" diff --git a/test/cmdlineTests/strict_asm_debug_info_print_location_only/output b/test/cmdlineTests/strict_asm_debug_info_print_location_only/output index 17d2f50e2e15..06448d25ab42 100644 --- a/test/cmdlineTests/strict_asm_debug_info_print_location_only/output +++ b/test/cmdlineTests/strict_asm_debug_info_print_location_only/output @@ -1,5 +1,5 @@ -======= strict_asm_debug_info_print_location_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: /// @use-src 0:"input.sol" diff --git a/test/cmdlineTests/strict_asm_debug_info_print_none/output b/test/cmdlineTests/strict_asm_debug_info_print_none/output index 51f779490ab7..93fc5c73e53b 100644 --- a/test/cmdlineTests/strict_asm_debug_info_print_none/output +++ b/test/cmdlineTests/strict_asm_debug_info_print_none/output @@ -1,5 +1,5 @@ -======= strict_asm_debug_info_print_none/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: /// @use-src 0:"input.sol" diff --git a/test/cmdlineTests/strict_asm_eof_container_osaka/output b/test/cmdlineTests/strict_asm_eof_container_osaka/output index 81f01798a766..3582e09d6cb6 100644 --- a/test/cmdlineTests/strict_asm_eof_container_osaka/output +++ b/test/cmdlineTests/strict_asm_eof_container_osaka/output @@ -1,5 +1,5 @@ -======= strict_asm_eof_container_osaka/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output index 677c49b88a1b..9d256a5dd493 100644 --- a/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output @@ -1,5 +1,5 @@ -======= strict_asm_eof_dataloadn_osaka/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/strict_asm_evm_version_byzantium/output b/test/cmdlineTests/strict_asm_evm_version_byzantium/output index 2840e1d2b697..a43e6e47c34c 100644 --- a/test/cmdlineTests/strict_asm_evm_version_byzantium/output +++ b/test/cmdlineTests/strict_asm_evm_version_byzantium/output @@ -1,5 +1,5 @@ -======= strict_asm_evm_version_byzantium/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -11,5 +11,5 @@ Binary representation: 00 Text representation: - /* "strict_asm_evm_version_byzantium/input.yul":27:34 */ + /* "input.yul":27:34 */ stop diff --git a/test/cmdlineTests/strict_asm_evm_version_constantinople/output b/test/cmdlineTests/strict_asm_evm_version_constantinople/output index 9362866b43dc..a43e6e47c34c 100644 --- a/test/cmdlineTests/strict_asm_evm_version_constantinople/output +++ b/test/cmdlineTests/strict_asm_evm_version_constantinople/output @@ -1,5 +1,5 @@ -======= strict_asm_evm_version_constantinople/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -11,5 +11,5 @@ Binary representation: 00 Text representation: - /* "strict_asm_evm_version_constantinople/input.yul":27:34 */ + /* "input.yul":27:34 */ stop diff --git a/test/cmdlineTests/strict_asm_jump/err b/test/cmdlineTests/strict_asm_jump/err index c0001f382533..419701b46660 100644 --- a/test/cmdlineTests/strict_asm_jump/err +++ b/test/cmdlineTests/strict_asm_jump/err @@ -1,5 +1,5 @@ Error: Function "jump" not found. - --> strict_asm_jump/input.yul:1:3: + --> input.yul:1:3: | 1 | { jump(1) } | ^^^^ diff --git a/test/cmdlineTests/strict_asm_msize_with_optimizer/output b/test/cmdlineTests/strict_asm_msize_with_optimizer/output index fbc1e69fac24..7f170e22f699 100644 --- a/test/cmdlineTests/strict_asm_msize_with_optimizer/output +++ b/test/cmdlineTests/strict_asm_msize_with_optimizer/output @@ -1,5 +1,5 @@ -======= strict_asm_msize_with_optimizer/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_msize_without_optimizer/output b/test/cmdlineTests/strict_asm_msize_without_optimizer/output index ac19efbcbc78..2ba00372efca 100644 --- a/test/cmdlineTests/strict_asm_msize_without_optimizer/output +++ b/test/cmdlineTests/strict_asm_msize_without_optimizer/output @@ -1,5 +1,5 @@ -======= strict_asm_msize_without_optimizer/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_only_cr/err b/test/cmdlineTests/strict_asm_only_cr/err index 0879e4f212db..334ade78f75e 100644 --- a/test/cmdlineTests/strict_asm_only_cr/err +++ b/test/cmdlineTests/strict_asm_only_cr/err @@ -1,5 +1,5 @@ Error: Expected keyword "object". - --> strict_asm_only_cr/input.yul:1:2: + --> input.yul:1:2: | 1 | | ^ diff --git a/test/cmdlineTests/strict_asm_optimizer_steps/output b/test/cmdlineTests/strict_asm_optimizer_steps/output index 58c91976185c..4e20c6218f87 100644 --- a/test/cmdlineTests/strict_asm_optimizer_steps/output +++ b/test/cmdlineTests/strict_asm_optimizer_steps/output @@ -1,5 +1,5 @@ -======= strict_asm_optimizer_steps/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "C_6" { @@ -27,58 +27,58 @@ Binary representation: 608060405234601357600c60185f39600c5ff35b5f80fdfe608060405236155f555f80fd Text representation: - /* "strict_asm_optimizer_steps/input.yul":59:62 */ + /* "input.yul":59:62 */ 0x80 - /* "strict_asm_optimizer_steps/input.yul":55:57 */ + /* "input.yul":55:57 */ 0x40 - /* "strict_asm_optimizer_steps/input.yul":48:63 */ + /* "input.yul":48:63 */ mstore - /* "strict_asm_optimizer_steps/input.yul":79:90 */ + /* "input.yul":79:90 */ callvalue - /* "strict_asm_optimizer_steps/input.yul":76:107 */ + /* "input.yul":76:107 */ tag_1 jumpi - /* "strict_asm_optimizer_steps/input.yul":160:184 */ + /* "input.yul":160:184 */ dataSize(sub_0) - /* "strict_asm_optimizer_steps/input.yul":132:158 */ + /* "input.yul":132:158 */ dataOffset(sub_0) - /* "strict_asm_optimizer_steps/input.yul":129:130 */ + /* "input.yul":129:130 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":120:185 */ + /* "input.yul":120:185 */ codecopy - /* "strict_asm_optimizer_steps/input.yul":208:232 */ + /* "input.yul":208:232 */ dataSize(sub_0) - /* "strict_asm_optimizer_steps/input.yul":205:206 */ + /* "input.yul":205:206 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":198:233 */ + /* "input.yul":198:233 */ return - /* "strict_asm_optimizer_steps/input.yul":91:107 */ + /* "input.yul":91:107 */ tag_1: - /* "strict_asm_optimizer_steps/input.yul":103:104 */ + /* "input.yul":103:104 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":93:105 */ + /* "input.yul":93:105 */ dup1 revert stop sub_0: assembly { - /* "strict_asm_optimizer_steps/input.yul":334:337 */ + /* "input.yul":334:337 */ 0x80 - /* "strict_asm_optimizer_steps/input.yul":330:332 */ + /* "input.yul":330:332 */ 0x40 - /* "strict_asm_optimizer_steps/input.yul":323:338 */ + /* "input.yul":323:338 */ mstore - /* "strict_asm_optimizer_steps/input.yul":372:386 */ + /* "input.yul":372:386 */ calldatasize - /* "strict_asm_optimizer_steps/input.yul":365:387 */ + /* "input.yul":365:387 */ iszero - /* "strict_asm_optimizer_steps/input.yul":362:363 */ + /* "input.yul":362:363 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":355:388 */ + /* "input.yul":355:388 */ sstore - /* "strict_asm_optimizer_steps/input.yul":415:416 */ + /* "input.yul":415:416 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":405:417 */ + /* "input.yul":405:417 */ dup1 revert } diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/output b/test/cmdlineTests/strict_asm_output_selection_asm_only/output index 317c9a9ae2fd..08932887f114 100644 --- a/test/cmdlineTests/strict_asm_output_selection_asm_only/output +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/output @@ -1,12 +1,12 @@ -======= strict_asm_output_selection_asm_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Text representation: - /* "strict_asm_output_selection_asm_only/input.yul":41:43 */ + /* "input.yul":41:43 */ 0x2a - /* "strict_asm_output_selection_asm_only/input.yul":38:39 */ + /* "input.yul":38:39 */ 0x00 - /* "strict_asm_output_selection_asm_only/input.yul":31:44 */ + /* "input.yul":31:44 */ sstore - /* "strict_asm_output_selection_asm_only/input.yul":27:48 */ + /* "input.yul":27:48 */ stop diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/output b/test/cmdlineTests/strict_asm_output_selection_bin_only/output index 86d249576805..4edd88b33146 100644 --- a/test/cmdlineTests/strict_asm_output_selection_bin_only/output +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/output @@ -1,5 +1,5 @@ -======= strict_asm_output_selection_bin_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Binary representation: 602a5f5500 diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output index 1fa4b72c7e2b..15174c71c8d3 100644 --- a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output @@ -1,5 +1,5 @@ -======= strict_asm_output_selection_ir_optimized_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_warning/err b/test/cmdlineTests/strict_asm_warning/err index 0661ae1ffec2..be47fb6ad90d 100644 --- a/test/cmdlineTests/strict_asm_warning/err +++ b/test/cmdlineTests/strict_asm_warning/err @@ -1,5 +1,5 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct(0) | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning/output b/test/cmdlineTests/strict_asm_warning/output index 71cb2ce69a09..b71411dae89d 100644 --- a/test/cmdlineTests/strict_asm_warning/output +++ b/test/cmdlineTests/strict_asm_warning/output @@ -1,5 +1,5 @@ -======= strict_asm_warning/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_warning_and_error_optimize/err b/test/cmdlineTests/strict_asm_warning_and_error_optimize/err index 22366e3e7bf3..b008c021a832 100644 --- a/test/cmdlineTests/strict_asm_warning_and_error_optimize/err +++ b/test/cmdlineTests/strict_asm_warning_and_error_optimize/err @@ -1,11 +1,11 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning_and_error_optimize/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct() | ^^^^^^^^^^^^ Error: Function "selfdestruct" expects 1 arguments but got 0. - --> strict_asm_warning_and_error_optimize/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct() | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize/err b/test/cmdlineTests/strict_asm_warning_optimize/err index 098aa00baf69..be47fb6ad90d 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize/err +++ b/test/cmdlineTests/strict_asm_warning_optimize/err @@ -1,5 +1,5 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning_optimize/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct(0) | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize/output b/test/cmdlineTests/strict_asm_warning_optimize/output index d933dcb05525..b71411dae89d 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize/output +++ b/test/cmdlineTests/strict_asm_warning_optimize/output @@ -1,5 +1,5 @@ -======= strict_asm_warning_optimize/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err index 4535680baa59..4465b2c242d9 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err @@ -1,5 +1,5 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning_optimize_unreachable/input.yul:7:5: + --> input.yul:7:5: | 7 | selfdestruct(0) | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output index 508e9d8ed4ef..a2c2516af78d 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output @@ -1,5 +1,5 @@ -======= strict_asm_warning_optimize_unreachable/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index c79692c3c035..e0bb1af40952 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -1,5 +1,5 @@ -======= strict_asm_yul_cfg_json_export/input.yul (EVM) ======= +======= input.yul (EVM) ======= Yul Control Flow Graph: { diff --git a/test/cmdlineTests/structured_documentation_source_location/err b/test/cmdlineTests/structured_documentation_source_location/err index 1f69adf4f63d..51d3a652ee77 100644 --- a/test/cmdlineTests/structured_documentation_source_location/err +++ b/test/cmdlineTests/structured_documentation_source_location/err @@ -1,11 +1,11 @@ Error: Documentation tag "@return No value returned" does not contain the name of its return parameter. - --> structured_documentation_source_location/input.sol:4:5: + --> input.sol:4:5: | 4 | /// @param id Some identifier | ^ (Relevant source part starts here and spans across multiple lines). Error: Documentation tag "@return No value returned" does not contain the name of its return parameter. - --> structured_documentation_source_location/input.sol:8:5: + --> input.sol:8:5: | 8 | /// @return No value returned | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line/err b/test/cmdlineTests/too_long_line/err index 25620bd4c5e2..626812e5f7bd 100644 --- a/test/cmdlineTests/too_long_line/err +++ b/test/cmdlineTests/too_long_line/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line/input.sol:5:164: + --> input.sol:5:164: | 5 | ... ffffffffffffffffffffffffffffffffff(announcementType Type, string Announcement, string ... | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_both_sides_short/err b/test/cmdlineTests/too_long_line_both_sides_short/err index 5992d6ea9387..194047c580b4 100644 --- a/test/cmdlineTests/too_long_line_both_sides_short/err +++ b/test/cmdlineTests/too_long_line_both_sides_short/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_both_sides_short/input.sol:5:15: + --> input.sol:5:15: | 5 | function f(announcementTypeXXXXXXXXXXXXXXXXXXX ... XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Type, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_edge_in/err b/test/cmdlineTests/too_long_line_edge_in/err index 1d96ea4cdc03..161e3a20bc93 100644 --- a/test/cmdlineTests/too_long_line_edge_in/err +++ b/test/cmdlineTests/too_long_line_edge_in/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_edge_in/input.sol:5:36: + --> input.sol:5:36: | 5 | function ffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Ty, string A) onlyOwner external { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_edge_out/err b/test/cmdlineTests/too_long_line_edge_out/err index 3b3b4ee490b9..6aa17fc0335f 100644 --- a/test/cmdlineTests/too_long_line_edge_out/err +++ b/test/cmdlineTests/too_long_line_edge_out/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_edge_out/input.sol:5:37: + --> input.sol:5:37: | 5 | ... function fffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Typ, string A) onlyOwner external ... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_left_short/err b/test/cmdlineTests/too_long_line_left_short/err index 4f2359739076..25c35177d344 100644 --- a/test/cmdlineTests/too_long_line_left_short/err +++ b/test/cmdlineTests/too_long_line_left_short/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_left_short/input.sol:5:15: + --> input.sol:5:15: | 5 | function f(announcementType Type, string Announcement, string ... | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_multiline/err b/test/cmdlineTests/too_long_line_multiline/err index 4523938c6ee7..bfa99eed3c8b 100644 --- a/test/cmdlineTests/too_long_line_multiline/err +++ b/test/cmdlineTests/too_long_line_multiline/err @@ -1,5 +1,5 @@ Error: No visibility specified. Did you intend to add "public"? - --> too_long_line_multiline/input.sol:5:5: + --> input.sol:5:5: | 5 | function f() returns (bytes1 _b, by ... _b7, bytes22 _b22, bytes32 _b32) { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/too_long_line_right_short/err b/test/cmdlineTests/too_long_line_right_short/err index 7aa26ff074c5..f17f273b1c4e 100644 --- a/test/cmdlineTests/too_long_line_right_short/err +++ b/test/cmdlineTests/too_long_line_right_short/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_right_short/input.sol:5:164: + --> input.sol:5:164: | 5 | ... ffffffffffffffffffffffffffffffffff(announcementType Type, | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/transient_storage_layout/output b/test/cmdlineTests/transient_storage_layout/output index 0736271b44ad..846cb947d885 100644 --- a/test/cmdlineTests/transient_storage_layout/output +++ b/test/cmdlineTests/transient_storage_layout/output @@ -1,11 +1,11 @@ -======= transient_storage_layout/input.sol:C ======= +======= input.sol:C ======= Contract Transient Storage Layout: { "storage": [ { "astId": 4, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "x", "offset": 0, "slot": "0", @@ -13,7 +13,7 @@ Contract Transient Storage Layout: }, { "astId": 8, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "w", "offset": 0, "slot": "1", @@ -21,7 +21,7 @@ Contract Transient Storage Layout: }, { "astId": 12, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "b", "offset": 20, "slot": "1", @@ -29,7 +29,7 @@ Contract Transient Storage Layout: }, { "astId": 15, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "d", "offset": 0, "slot": "2", @@ -60,7 +60,7 @@ Contract Transient Storage Layout: } } -======= transient_storage_layout/input.sol:D ======= +======= input.sol:D ======= Contract Transient Storage Layout: { "storage": [] diff --git a/test/cmdlineTests/transient_storage_layout_value_types/input.json b/test/cmdlineTests/transient_storage_layout_value_types/input.json index 65d9a2231b90..2b903a2aea0d 100644 --- a/test/cmdlineTests/transient_storage_layout_value_types/input.json +++ b/test/cmdlineTests/transient_storage_layout_value_types/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["transient_storage_layout_value_types/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json index e649fc838b82..7a12ca85c985 100644 --- a/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json +++ b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["transient_storage_layout_value_types_interleaved_with_storage/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json b/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json index ee7fb0dec3b7..2b903a2aea0d 100644 --- a/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json +++ b/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["transient_storage_layout_value_types_packed/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/undeployable_contract_empty_outputs/output b/test/cmdlineTests/undeployable_contract_empty_outputs/output index 123edc75ddd6..71059f17f1d5 100644 --- a/test/cmdlineTests/undeployable_contract_empty_outputs/output +++ b/test/cmdlineTests/undeployable_contract_empty_outputs/output @@ -1,5 +1,5 @@ -======= undeployable_contract_empty_outputs/input.sol:C ======= +======= input.sol:C ======= EVM assembly: null Gas estimation: @@ -21,7 +21,7 @@ Function signatures: Contract JSON ABI [] -======= undeployable_contract_empty_outputs/input.sol:I ======= +======= input.sol:I ======= EVM assembly: null Gas estimation: diff --git a/test/cmdlineTests/viair_abicoder_v1/err b/test/cmdlineTests/viair_abicoder_v1/err index 55f8ba4b91b3..29fa2acd04a0 100644 --- a/test/cmdlineTests/viair_abicoder_v1/err +++ b/test/cmdlineTests/viair_abicoder_v1/err @@ -1,5 +1,5 @@ Warning (2066): Contract requests the ABI coder v1, which is incompatible with the IR. Using ABI coder v2 instead. - --> viair_abicoder_v1/input.sol:4:1: + --> input.sol:4:1: | 4 | contract test { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/viair_abicoder_v1/output b/test/cmdlineTests/viair_abicoder_v1/output index 1c4d6c90e260..3d6a582889df 100644 --- a/test/cmdlineTests/viair_abicoder_v1/output +++ b/test/cmdlineTests/viair_abicoder_v1/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"viair_abicoder_v1/input.sol" +/// @use-src 0:"input.sol" object "test_11" { code { /// @src 0:79:169 "contract test {..." @@ -31,7 +31,7 @@ object "test_11" { /// @src 0:79:169 "contract test {..." } - /// @use-src 0:"viair_abicoder_v1/input.sol" + /// @use-src 0:"input.sol" object "test_11_deployed" { code { /// @src 0:79:169 "contract test {..." diff --git a/test/cmdlineTests/viair_msize_without_optimizer/output b/test/cmdlineTests/viair_msize_without_optimizer/output index f94c973bff3a..90c18ef947a1 100644 --- a/test/cmdlineTests/viair_msize_without_optimizer/output +++ b/test/cmdlineTests/viair_msize_without_optimizer/output @@ -1,5 +1,5 @@ -======= viair_msize_without_optimizer/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) jumpi(tag_4, iszero(callvalue)) @@ -173,7 +173,7 @@ sub_0: assembly { } Optimized IR: -/// @use-src 0:"viair_msize_without_optimizer/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { mstore(64, memoryguard(128)) @@ -192,7 +192,7 @@ object "C_7" { function constructor_C_7() { } } - /// @use-src 0:"viair_msize_without_optimizer/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { mstore(64, memoryguard(128)) diff --git a/test/cmdlineTests/viair_subobject_optimization/output b/test/cmdlineTests/viair_subobject_optimization/output index dafba2771c5d..523cff79e0fa 100644 --- a/test/cmdlineTests/viair_subobject_optimization/output +++ b/test/cmdlineTests/viair_subobject_optimization/output @@ -1,7 +1,7 @@ -======= viair_subobject_optimization/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x80 jumpi(tag_7, callvalue) 0x1f @@ -44,12 +44,12 @@ EVM assembly: jumpi mload sub(shl(0x48, 0x01), 0xbe) - /* "viair_subobject_optimization/input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ + /* "input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ eq - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7 jumpi - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ mload(0x40) dataSize(sub_0) swap1 @@ -58,13 +58,13 @@ EVM assembly: dup3 codecopy return - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7: 0x00 - /* "viair_subobject_optimization/input.sol":653:661 revert() */ + /* "input.sol":653:661 revert() */ dup1 revert - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ tag_3: mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x41) @@ -72,7 +72,7 @@ tag_3: stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x00 dup1 revert @@ -81,9 +81,9 @@ sub_0: assembly { } -======= viair_subobject_optimization/input.sol:D ======= +======= input.sol:D ======= EVM assembly: - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ 0x80 dup1 0x40 @@ -103,7 +103,7 @@ tag_1: stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ 0x80 jumpi(tag_1, iszero(lt(calldatasize, 0x04))) 0x00 @@ -117,10 +117,10 @@ sub_0: assembly { tag_3: jumpi(tag_7, callvalue) jumpi(tag_7, slt(add(not(0x03), calldatasize), 0x00)) - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ dataSize(sub_0) swap1 - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ 0x3f dup3 add @@ -142,7 +142,7 @@ sub_0: assembly { swap2 dup3 mstore - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ dup3 dup2 mstore @@ -153,24 +153,24 @@ sub_0: assembly { dataOffset(sub_0) dup5 codecopy - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ dup2 mload swap3 dup4 swap2 - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ 0x20 - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ dup4 mstore mload dup1 swap2 dup2 - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ 0x20 - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ dup6 add mstore @@ -206,7 +206,7 @@ sub_0: assembly { stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x80 jumpi(tag_7, callvalue) 0x1f @@ -249,12 +249,12 @@ sub_0: assembly { jumpi mload sub(shl(0x48, 0x01), 0xbe) - /* "viair_subobject_optimization/input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ + /* "input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ eq - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7 jumpi - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ mload(0x40) dataSize(sub_0) swap1 @@ -263,13 +263,13 @@ sub_0: assembly { dup3 codecopy return - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7: 0x00 - /* "viair_subobject_optimization/input.sol":653:661 revert() */ + /* "input.sol":653:661 revert() */ dup1 revert - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ tag_3: mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x41) @@ -277,7 +277,7 @@ sub_0: assembly { stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x00 dup1 revert diff --git a/test/cmdlineTests/viair_subobjects/err b/test/cmdlineTests/viair_subobjects/err index 5046525bef7a..66ebf4229caf 100644 --- a/test/cmdlineTests/viair_subobjects/err +++ b/test/cmdlineTests/viair_subobjects/err @@ -1,5 +1,5 @@ Warning: Unused local variable. - --> viair_subobjects/input.sol:8:9: + --> input.sol:8:9: | 8 | C c = new C(); | ^^^ diff --git a/test/cmdlineTests/viair_subobjects/output b/test/cmdlineTests/viair_subobjects/output index 7a6bc8e6570b..783756e67681 100644 --- a/test/cmdlineTests/viair_subobjects/output +++ b/test/cmdlineTests/viair_subobjects/output @@ -1,11 +1,11 @@ -======= viair_subobjects/input.sol:C ======= +======= input.sol:C ======= Binary: Binary of the runtime part: Optimized IR: -/// @use-src 0:"viair_subobjects/input.sol" +/// @use-src 0:"input.sol" object "C_3" { code { { @@ -18,7 +18,7 @@ object "C_3" { return(_1, _2) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { @@ -31,13 +31,13 @@ object "C_3" { } -======= viair_subobjects/input.sol:D ======= +======= input.sol:D ======= Binary: Binary of the runtime part: Optimized IR: -/// @use-src 0:"viair_subobjects/input.sol" +/// @use-src 0:"input.sol" object "D_16" { code { { @@ -50,7 +50,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "D_16_deployed" { code { { @@ -88,7 +88,7 @@ object "D_16" { revert(0, 0) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3" { code { { @@ -101,7 +101,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 0508769d7cb0..9affc4206939 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -1,5 +1,5 @@ -======= yul_cfg_json_export/input.sol:C ======= +======= input.sol:C ======= Yul Control Flow Graph: { "C_19": { @@ -447,7 +447,7 @@ Yul Control Flow Graph: "type": "Object" } -======= yul_cfg_json_export/input.sol:D ======= +======= input.sol:D ======= Yul Control Flow Graph: { "D_38": { @@ -2127,6 +2127,6 @@ Yul Control Flow Graph: "type": "Object" } -======= yul_cfg_json_export/input.sol:I ======= +======= input.sol:I ======= Yul Control Flow Graph: null diff --git a/test/cmdlineTests/yul_function_name_clashes/output b/test/cmdlineTests/yul_function_name_clashes/output index 2c54b6f50893..1d319d284e5b 100644 --- a/test/cmdlineTests/yul_function_name_clashes/output +++ b/test/cmdlineTests/yul_function_name_clashes/output @@ -1,5 +1,5 @@ -======= yul_function_name_clashes/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/yul_function_name_clashes_different_params/output b/test/cmdlineTests/yul_function_name_clashes_different_params/output index 85884a6a0ede..fdffb0c31270 100644 --- a/test/cmdlineTests/yul_function_name_clashes_different_params/output +++ b/test/cmdlineTests/yul_function_name_clashes_different_params/output @@ -1,5 +1,5 @@ -======= yul_function_name_clashes_different_params/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -23,37 +23,37 @@ Binary representation: 60056011565b600d60706016565b9055005b5f3590565b359056 Text representation: - /* "yul_function_name_clashes_different_params/input.yul":92:95 */ + /* "input.yul":92:95 */ tag_3 tag_1 jump // in tag_3: - /* "yul_function_name_clashes_different_params/input.yul":113:122 */ + /* "input.yul":113:122 */ tag_4 - /* "yul_function_name_clashes_different_params/input.yul":117:121 */ + /* "input.yul":117:121 */ 0x70 - /* "yul_function_name_clashes_different_params/input.yul":113:122 */ + /* "input.yul":113:122 */ tag_2 jump // in tag_4: - /* "yul_function_name_clashes_different_params/input.yul":135:147 */ + /* "input.yul":135:147 */ swap1 sstore - /* "yul_function_name_clashes_different_params/input.yul":27:284 */ + /* "input.yul":27:284 */ stop - /* "yul_function_name_clashes_different_params/input.yul":166:216 */ + /* "input.yul":166:216 */ tag_1: - /* "yul_function_name_clashes_different_params/input.yul":212:213 */ + /* "input.yul":212:213 */ 0x00 - /* "yul_function_name_clashes_different_params/input.yul":199:214 */ + /* "input.yul":199:214 */ calldataload - /* "yul_function_name_clashes_different_params/input.yul":166:216 */ + /* "input.yul":166:216 */ swap1 jump // out - /* "yul_function_name_clashes_different_params/input.yul":225:278 */ + /* "input.yul":225:278 */ tag_2: - /* "yul_function_name_clashes_different_params/input.yul":261:276 */ + /* "input.yul":261:276 */ calldataload - /* "yul_function_name_clashes_different_params/input.yul":225:278 */ + /* "input.yul":225:278 */ swap1 jump // out diff --git a/test/cmdlineTests/yul_optimize_runs/output b/test/cmdlineTests/yul_optimize_runs/output index 589f8ce1a12c..ec3dab457213 100644 --- a/test/cmdlineTests/yul_optimize_runs/output +++ b/test/cmdlineTests/yul_optimize_runs/output @@ -1,5 +1,5 @@ -======= yul_optimize_runs/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "RunsTest1" { @@ -24,28 +24,28 @@ Binary representation: 602480600a5f395ff3fe7fabc12345000000000000000000000000000000000000000000000000000000005f5500 Text representation: - /* "yul_optimize_runs/input.yul":64:92 */ + /* "input.yul":64:92 */ dataSize(sub_0) - /* "yul_optimize_runs/input.yul":117:147 */ + /* "input.yul":117:147 */ dup1 dataOffset(sub_0) - /* "yul_optimize_runs/input.yul":114:115 */ + /* "input.yul":114:115 */ 0x00 - /* "yul_optimize_runs/input.yul":105:152 */ + /* "input.yul":105:152 */ codecopy - /* "yul_optimize_runs/input.yul":172:173 */ + /* "input.yul":172:173 */ 0x00 - /* "yul_optimize_runs/input.yul":165:178 */ + /* "input.yul":165:178 */ return stop sub_0: assembly { - /* "yul_optimize_runs/input.yul":282:348 */ + /* "input.yul":282:348 */ 0xabc1234500000000000000000000000000000000000000000000000000000000 - /* "yul_optimize_runs/input.yul":279:280 */ + /* "input.yul":279:280 */ 0x00 - /* "yul_optimize_runs/input.yul":272:349 */ + /* "input.yul":272:349 */ sstore - /* "yul_optimize_runs/input.yul":240:373 */ + /* "input.yul":240:373 */ stop } diff --git a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output index 7b948303ee43..744bc03a8c6e 100644 --- a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output +++ b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output @@ -1,4 +1,4 @@ -======= yul_optimizer_disabled_sequence_empty/input.sol:C ======= +======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"yul_optimizer_disabled_sequence_empty/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"yul_optimizer_disabled_sequence_empty/input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} diff --git a/test/cmdlineTests/yul_optimizer_steps/output b/test/cmdlineTests/yul_optimizer_steps/output index bb68a48fa809..f9484d2b4491 100644 --- a/test/cmdlineTests/yul_optimizer_steps/output +++ b/test/cmdlineTests/yul_optimizer_steps/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { { @@ -18,7 +18,7 @@ object "C_7" { function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } } - /// @use-src 0:"yul_optimizer_steps/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output index 9687abf643b3..26be9469862a 100644 --- a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output +++ b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_nested_brackets/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -21,7 +21,7 @@ object "C_6" { function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } } - /// @use-src 0:"yul_optimizer_steps_nested_brackets/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_short_sequence/output b/test/cmdlineTests/yul_optimizer_steps_short_sequence/output index dc77ce3c53e7..e93958a5d619 100644 --- a/test/cmdlineTests/yul_optimizer_steps_short_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_short_sequence/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_short_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_8" { code { { @@ -9,7 +9,7 @@ object "C_8" { revert(0, 0) } } - /// @use-src 0:"yul_optimizer_steps_short_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_8_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output b/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output index 01641c53bc30..bbfd22e9bdfe 100644 --- a/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_with_empty_cleanup_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_8" { code { { @@ -10,7 +10,7 @@ object "C_8" { revert(0, usr$a) } } - /// @use-src 0:"yul_optimizer_steps_with_empty_cleanup_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_8_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output b/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output index b13e6e2823ff..bbfd22e9bdfe 100644 --- a/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_with_empty_optimization_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_8" { code { { @@ -10,7 +10,7 @@ object "C_8" { revert(0, usr$a) } } - /// @use-src 0:"yul_optimizer_steps_with_empty_optimization_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_8_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err index 95e30df2e83d..d87be1839ccb 100644 --- a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err +++ b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err @@ -1,11 +1,11 @@ Warning: Unused local variable. - --> yul_optimizer_steps_without_optimize_empty_sequence/input.sol:13:9: + --> input.sol:13:9: | 13 | uint b = a; | ^^^^^^ Warning: Unused local variable. - --> yul_optimizer_steps_without_optimize_empty_sequence/input.sol:14:9: + --> input.sol:14:9: | 14 | uint c = a; | ^^^^^^ diff --git a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output index 6873abe60e47..a7b037775f2c 100644 --- a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output @@ -1,7 +1,7 @@ -======= yul_optimizer_steps_without_optimize_empty_sequence/input.sol:C ======= +======= input.sol:C ======= Optimized IR: -/// @use-src 0:"yul_optimizer_steps_without_optimize_empty_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_28" { code { { @@ -24,7 +24,7 @@ object "C_28" { function constructor_C() { } } - /// @use-src 0:"yul_optimizer_steps_without_optimize_empty_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_28_deployed" { code { { @@ -130,4 +130,4 @@ object "C_28" { } Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} diff --git a/test/cmdlineTests/yul_verbatim/output b/test/cmdlineTests/yul_verbatim/output index 60fc7e6d1f46..33f86b2992be 100644 --- a/test/cmdlineTests/yul_verbatim/output +++ b/test/cmdlineTests/yul_verbatim/output @@ -1,5 +1,5 @@ -======= yul_verbatim/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -20,38 +20,38 @@ Binary representation: 6002808103808261626382815564656678797a010203040506070900010203040506070900010203040506070900010201020304050607090001020304050607090001020304050607090001026009905050505050 Text representation: - /* "yul_verbatim/input.yul":15:16 */ + /* "input.yul":15:16 */ 0x02 - /* "yul_verbatim/input.yul":37:38 */ + /* "input.yul":37:38 */ dup1 - /* "yul_verbatim/input.yul":34:35 */ + /* "input.yul":34:35 */ dup2 - /* "yul_verbatim/input.yul":30:39 */ + /* "input.yul":30:39 */ sub - /* "yul_verbatim/input.yul":78:79 */ + /* "input.yul":78:79 */ dup1 - /* "yul_verbatim/input.yul":75:76 */ + /* "input.yul":75:76 */ dup3 - /* "yul_verbatim/input.yul":53:80 */ + /* "input.yul":53:80 */ verbatimbytecode_616263 - /* "yul_verbatim/input.yul":95:96 */ + /* "input.yul":95:96 */ dup3 - /* "yul_verbatim/input.yul":92:93 */ + /* "input.yul":92:93 */ dup2 - /* "yul_verbatim/input.yul":85:97 */ + /* "input.yul":85:97 */ sstore - /* "yul_verbatim/input.yul":111:132 */ + /* "input.yul":111:132 */ verbatimbytecode_646566 - /* "yul_verbatim/input.yul":137:158 */ + /* "input.yul":137:158 */ verbatimbytecode_78797a - /* "yul_verbatim/input.yul":189:326 */ + /* "input.yul":189:326 */ verbatimbytecode_01020304050607090001020304050607090001020304050607090001020102030405060709000102030405060709000102030405060709000102 - /* "yul_verbatim/input.yul":336:337 */ + /* "input.yul":336:337 */ 0x09 - /* "yul_verbatim/input.yul":331:337 */ + /* "input.yul":331:337 */ swap1 pop - /* "yul_verbatim/input.yul":0:339 */ + /* "input.yul":0:339 */ pop pop pop diff --git a/test/cmdlineTests/yul_verbatim_msize/output b/test/cmdlineTests/yul_verbatim_msize/output index f684bac21752..b0acd819d8d1 100644 --- a/test/cmdlineTests/yul_verbatim_msize/output +++ b/test/cmdlineTests/yul_verbatim_msize/output @@ -1,5 +1,5 @@ -======= yul_verbatim_msize/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -17,19 +17,19 @@ Binary representation: 6120005150616160025f5500 Text representation: - /* "yul_verbatim_msize/input.yul":61:67 */ + /* "input.yul":61:67 */ 0x2000 - /* "yul_verbatim_msize/input.yul":55:68 */ + /* "input.yul":55:68 */ mload - /* "yul_verbatim_msize/input.yul":51:69 */ + /* "input.yul":51:69 */ pop - /* "yul_verbatim_msize/input.yul":82:102 */ + /* "input.yul":82:102 */ verbatimbytecode_6161 - /* "yul_verbatim_msize/input.yul":125:126 */ + /* "input.yul":125:126 */ 0x02 - /* "yul_verbatim_msize/input.yul":122:123 */ + /* "input.yul":122:123 */ 0x00 - /* "yul_verbatim_msize/input.yul":115:127 */ + /* "input.yul":115:127 */ sstore - /* "yul_verbatim_msize/input.yul":27:143 */ + /* "input.yul":27:143 */ stop From 880b61bd33f6df5c05d77671f6b534be2957e100 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 13 Feb 2025 15:30:25 +0100 Subject: [PATCH 057/121] SMTChecker: Refactor handling of ConstantCondition verification target --- libsolidity/formal/BMC.cpp | 149 +++++++++++++++++-------------------- libsolidity/formal/BMC.h | 30 +++++--- 2 files changed, 90 insertions(+), 89 deletions(-) diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 6dcd856ee2af..4b494d6236ac 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -247,14 +247,8 @@ bool BMC::visit(IfStatement const& _node) m_context.pushSolver(); _node.condition().accept(*this); - // We ignore called functions here because they have - // specific input values. - if (isRootFunction() && !isInsideLoop()) - addVerificationTarget( - VerificationTargetType::ConstantCondition, - expr(_node.condition()), - &_node.condition() - ); + checkIfConditionIsConstant(_node.condition()); + m_context.popSolver(); resetVariableIndices(std::move(indicesBeforePush)); @@ -283,13 +277,7 @@ bool BMC::visit(Conditional const& _op) auto indicesBeforePush = copyVariableIndices(); m_context.pushSolver(); _op.condition().accept(*this); - - if (isRootFunction() && !isInsideLoop()) - addVerificationTarget( - VerificationTargetType::ConstantCondition, - expr(_op.condition()), - &_op.condition() - ); + checkIfConditionIsConstant(_op.condition()); m_context.popSolver(); resetVariableIndices(std::move(indicesBeforePush)); @@ -690,12 +678,7 @@ void BMC::visitRequire(FunctionCall const& _funCall) auto const& args = _funCall.arguments(); solAssert(args.size() >= 1, ""); solAssert(args.front()->annotation().type->category() == Type::Category::Bool, ""); - if (isRootFunction() && !isInsideLoop()) - addVerificationTarget( - VerificationTargetType::ConstantCondition, - expr(*args.front()), - args.front().get() - ); + checkIfConditionIsConstant(*args.front()); } void BMC::visitAddMulMod(FunctionCall const& _funCall) @@ -933,9 +916,6 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target) switch (_target.type) { - case VerificationTargetType::ConstantCondition: - checkConstantCondition(_target); - break; case VerificationTargetType::Underflow: checkUnderflow(_target); break; @@ -951,19 +931,70 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target) case VerificationTargetType::Assert: checkAssert(_target); break; + case VerificationTargetType::ConstantCondition: + solAssert(false, "Checks for constant condition are handled separately"); default: solAssert(false, ""); } } -void BMC::checkConstantCondition(BMCVerificationTarget& _target) +void BMC::checkIfConditionIsConstant(Expression const& _condition) { - checkBooleanNotConstant( - *_target.expression, - _target.constraints, - _target.value, - _target.callStack - ); + if ( + !m_settings.targets.has(VerificationTargetType::ConstantCondition) || + (m_currentContract && !shouldEncode(*m_currentContract)) + ) + return; + + // We ignore called functions here because they have specific input values. + // Also, expressions inside loop can have different values in different iterations. + if (!isRootFunction() || isInsideLoop()) + return; + + // Do not check for const-ness if this is a literal. + if (dynamic_cast(&_condition)) + return; + + auto [canBeTrue, canBeFalse] = checkBooleanNotConstant(currentPathConditions() && m_context.assertions(), expr(_condition)); + + // Report based on the result of the checks + if (canBeTrue == CheckResult::ERROR || canBeFalse == CheckResult::ERROR) + m_errorReporter.warning(8592_error, _condition.location(), "BMC: Error trying to invoke SMT solver."); + else if (canBeTrue == CheckResult::CONFLICTING || canBeFalse == CheckResult::CONFLICTING) + m_errorReporter.warning(3356_error, _condition.location(), "BMC: At least two SMT solvers provided conflicting answers. Results might not be sound."); + else if (canBeTrue == CheckResult::UNKNOWN || canBeFalse == CheckResult::UNKNOWN) + { + // Not enough information to make definite claims. + } + else if (canBeTrue == CheckResult::SATISFIABLE && canBeFalse == CheckResult::SATISFIABLE) + { + // Condition can be both true and false for some program runs. + } + + else if (canBeTrue == CheckResult::UNSATISFIABLE && canBeFalse == CheckResult::UNSATISFIABLE) + m_errorReporter.warning(2512_error, _condition.location(), "BMC: Condition unreachable.", SMTEncoder::callStackMessage(m_callStack)); + else + { + std::string description; + if (canBeFalse == smtutil::CheckResult::UNSATISFIABLE) + { + smtAssert(canBeTrue == smtutil::CheckResult::SATISFIABLE); + description = "BMC: Condition is always true."; + } + else + { + smtAssert(canBeTrue == smtutil::CheckResult::UNSATISFIABLE); + smtAssert(canBeFalse == smtutil::CheckResult::SATISFIABLE); + description = "BMC: Condition is always false."; + } + m_errorReporter.warning( + 6838_error, + _condition.location(), + description, + SMTEncoder::callStackMessage(m_callStack) + ); + } + } void BMC::checkUnderflow(BMCVerificationTarget& _target) @@ -1068,6 +1099,7 @@ void BMC::addVerificationTarget( Expression const* _expression ) { + smtAssert(_type != VerificationTargetType::ConstantCondition, "Checks for constant condition are handled separately"); if (!m_settings.targets.has(_type) || (m_currentContract && !shouldAnalyzeVerificationTargetsFor(*m_currentContract))) return; @@ -1081,10 +1113,7 @@ void BMC::addVerificationTarget( m_callStack, modelExpressions() }; - if (_type == VerificationTargetType::ConstantCondition) - checkVerificationTarget(target); - else - m_verificationTargets.emplace_back(std::move(target)); + m_verificationTargets.emplace_back(std::move(target)); } /// Solving. @@ -1188,62 +1217,22 @@ void BMC::checkCondition( m_interface->pop(); } -void BMC::checkBooleanNotConstant( - Expression const& _condition, +BMC::ConstantExpressionCheckResult BMC::checkBooleanNotConstant( smtutil::Expression const& _constraints, - smtutil::Expression const& _value, - std::vector const& _callStack + smtutil::Expression const& _condition ) { - // Do not check for const-ness if this is a constant. - if (dynamic_cast(&_condition)) - return; - m_interface->push(); - m_interface->addAssertion(_constraints && _value); + m_interface->addAssertion(_constraints && _condition); auto positiveResult = checkSatisfiable(); m_interface->pop(); m_interface->push(); - m_interface->addAssertion(_constraints && !_value); + m_interface->addAssertion(_constraints && !_condition); auto negatedResult = checkSatisfiable(); m_interface->pop(); - if (positiveResult == smtutil::CheckResult::ERROR || negatedResult == smtutil::CheckResult::ERROR) - m_errorReporter.warning(8592_error, _condition.location(), "BMC: Error trying to invoke SMT solver."); - else if (positiveResult == smtutil::CheckResult::CONFLICTING || negatedResult == smtutil::CheckResult::CONFLICTING) - m_errorReporter.warning(3356_error, _condition.location(), "BMC: At least two SMT solvers provided conflicting answers. Results might not be sound."); - else if (positiveResult == smtutil::CheckResult::SATISFIABLE && negatedResult == smtutil::CheckResult::SATISFIABLE) - { - // everything fine. - } - else if (positiveResult == smtutil::CheckResult::UNKNOWN || negatedResult == smtutil::CheckResult::UNKNOWN) - { - // can't do anything. - } - else if (positiveResult == smtutil::CheckResult::UNSATISFIABLE && negatedResult == smtutil::CheckResult::UNSATISFIABLE) - m_errorReporter.warning(2512_error, _condition.location(), "BMC: Condition unreachable.", SMTEncoder::callStackMessage(_callStack)); - else - { - std::string description; - if (positiveResult == smtutil::CheckResult::SATISFIABLE) - { - solAssert(negatedResult == smtutil::CheckResult::UNSATISFIABLE, ""); - description = "BMC: Condition is always true."; - } - else - { - solAssert(positiveResult == smtutil::CheckResult::UNSATISFIABLE, ""); - solAssert(negatedResult == smtutil::CheckResult::SATISFIABLE, ""); - description = "BMC: Condition is always false."; - } - m_errorReporter.warning( - 6838_error, - _condition.location(), - description, - SMTEncoder::callStackMessage(_callStack) - ); - } + return {.canBeTrue = positiveResult, .canBeFalse = negatedResult}; } std::pair> diff --git a/libsolidity/formal/BMC.h b/libsolidity/formal/BMC.h index a0ee9a3749c2..67d930c79194 100644 --- a/libsolidity/formal/BMC.h +++ b/libsolidity/formal/BMC.h @@ -161,7 +161,6 @@ class BMC: public SMTEncoder void checkVerificationTargets(); void checkVerificationTarget(BMCVerificationTarget& _target); - void checkConstantCondition(BMCVerificationTarget& _target); void checkUnderflow(BMCVerificationTarget& _target); void checkOverflow(BMCVerificationTarget& _target); void checkDivByZero(BMCVerificationTarget& _target); @@ -172,8 +171,13 @@ class BMC: public SMTEncoder smtutil::Expression const& _value, Expression const* _expression ); + /// Special handling of ConstantCondition verification target. + /// The target is checked immediately, unlike the other targets that are queued for checking at the end of analysis. + void checkIfConditionIsConstant(Expression const& _condition); //@} + + /// Solver related. //@{ /// Check that a condition can be satisfied. @@ -188,13 +192,18 @@ class BMC: public SMTEncoder std::string const& _additionalValueName = "", smtutil::Expression const* _additionalValue = nullptr ); - /// Checks that a boolean condition is not constant. Do not warn if the expression - /// is a literal constant. - void checkBooleanNotConstant( - Expression const& _condition, + + struct ConstantExpressionCheckResult + { + smtutil::CheckResult canBeTrue; + smtutil::CheckResult canBeFalse; + }; + + /// Checks whether the given boolean condition is either true or always false under given constraints. + /// Returns the results from the solver for these two checks. + ConstantExpressionCheckResult checkBooleanNotConstant( smtutil::Expression const& _constraints, - smtutil::Expression const& _value, - std::vector const& _callStack + smtutil::Expression const& _condition ); std::pair> checkSatisfiableAndGenerateModel(std::vector const& _expressionsToEvaluate); @@ -222,20 +231,23 @@ class BMC: public SMTEncoder /// Number of verification conditions that could not be proved. size_t m_unprovedAmt = 0; + /// Loop analysis + //@{ enum class LoopControlKind { Continue, Break }; - // Current path conditions and SSA indices for break or continue statement + /// Current path conditions and SSA indices for break or continue statement struct LoopControl { LoopControlKind kind; smtutil::Expression pathConditions; VariableIndices variableIndices; }; - // Loop control statements for every loop + /// Loop control statements for every loop std::stack> m_loopCheckpoints; + //@} }; } From d9083dc11aa70eb3fa6089102c637b31fc9e0a31 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 21 Mar 2025 18:04:51 +0100 Subject: [PATCH 058/121] SMTChecker: Loop conditions should be analyzed as in loop context in BMC Value of loop condition can change between iterations of the loop. Therefore, BMC should be in the "inside loop" state when analyzing loop conditions. --- Changelog.md | 1 + libsolidity/formal/BMC.cpp | 10 +++++++--- ..._first_iteration_and_constant_false_in_second.sol | 10 ++++++++++ ..._first_iteration_and_constant_false_in_second.sol | 12 ++++++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol create mode 100644 test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol diff --git a/Changelog.md b/Changelog.md index 525ed2d9e58b..e8ccbb525302 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: +* SMTChecker: Do not consider loop conditions as constant-condition verification target as this could cause incorrect reports and internal compiler errors. * SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`. * SMTChecker: Fix internal compiler error when string literal is used to initialize user-defined type based on fixed bytes. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 4b494d6236ac..8401c8dbfc0b 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -363,7 +363,9 @@ bool BMC::visit(WhileStatement const& _node) { //after loop iterations are done, we check the loop condition last final time auto indices = copyVariableIndices(); + m_loopCheckpoints.emplace(); _node.condition().accept(*this); + m_loopCheckpoints.pop(); loopCondition = expr(_node.condition()); // assert that the loop is complete m_context.addAssertion(!loopCondition || broke || !loopConditionOnPreviousIterations); @@ -391,13 +393,13 @@ bool BMC::visit(ForStatement const& _node) for (unsigned int i = 0; i < bmcLoopIterations; ++i) { auto indicesBefore = copyVariableIndices(); + m_loopCheckpoints.emplace(); if (_node.condition()) { _node.condition()->accept(*this); // values in loop condition might change during loop iteration forCondition = expr(*_node.condition()); } - m_loopCheckpoints.emplace(); auto indicesAfterCondition = copyVariableIndices(); pushPathCondition(forCondition); @@ -443,8 +445,10 @@ bool BMC::visit(ForStatement const& _node) auto indices = copyVariableIndices(); if (_node.condition()) { + m_loopCheckpoints.emplace(); _node.condition()->accept(*this); forCondition = expr(*_node.condition()); + m_loopCheckpoints.pop(); } // assert that the loop is complete m_context.addAssertion(!forCondition || broke || !forConditionOnPreviousIterations); @@ -932,9 +936,9 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target) checkAssert(_target); break; case VerificationTargetType::ConstantCondition: - solAssert(false, "Checks for constant condition are handled separately"); + smtAssert(false, "Checks for constant condition are handled separately"); default: - solAssert(false, ""); + smtAssert(false); } } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol new file mode 100644 index 000000000000..7e0a85b9b401 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol @@ -0,0 +1,10 @@ +contract Test { + function loop() public pure { + for (uint k = 0; (k == 0 ? true : false); k++) { + } + } +} +// ==== +// SMTEngine: bmc +// SMTTargets: constantCondition +// ---- diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol new file mode 100644 index 000000000000..b367cb803647 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol @@ -0,0 +1,12 @@ +contract Test { + function loop() public pure { + uint k = 0; + while (k == 0 ? true : false) { + ++k; + } + } +} +// ==== +// SMTEngine: bmc +// SMTTargets: constantCondition +// ---- From b1a9031f5875e8bfd2e8ac670818c954096b8543 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sat, 29 Mar 2025 20:11:58 +0100 Subject: [PATCH 059/121] SMTChecker: Clean up includes --- libsmtutil/SMTLib2Interface.cpp | 3 ++- libsmtutil/SMTPortfolio.h | 3 --- libsmtutil/SolverInterface.h | 3 ++- libsolidity/formal/ArraySlicePredicate.cpp | 2 ++ libsolidity/formal/ArraySlicePredicate.h | 4 ++-- libsolidity/formal/EncodingContext.cpp | 7 +++++++ libsolidity/formal/EncodingContext.h | 5 +---- libsolidity/formal/ExpressionFormatter.cpp | 2 ++ libsolidity/formal/Predicate.cpp | 2 +- libsolidity/formal/Predicate.h | 3 ++- libsolidity/formal/SymbolicTypes.cpp | 1 + libsolidity/formal/SymbolicTypes.h | 1 - libsolidity/formal/SymbolicVariables.cpp | 2 ++ libsolidity/formal/VariableUsage.cpp | 5 +---- 14 files changed, 25 insertions(+), 18 deletions(-) diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index 0430f0d21ea0..403989ca1aad 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -25,7 +25,8 @@ #include #include -#include +#include +#include #include #include diff --git a/libsmtutil/SMTPortfolio.h b/libsmtutil/SMTPortfolio.h index b445f40a2b69..59e0752a3471 100644 --- a/libsmtutil/SMTPortfolio.h +++ b/libsmtutil/SMTPortfolio.h @@ -20,10 +20,7 @@ #include -#include -#include -#include #include namespace solidity::smtutil diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index 2639ae024034..c434322d5d0f 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -26,7 +26,8 @@ #include #include -#include +#include +#include #include #include diff --git a/libsolidity/formal/ArraySlicePredicate.cpp b/libsolidity/formal/ArraySlicePredicate.cpp index 21d5fb1add29..67e635deb39c 100644 --- a/libsolidity/formal/ArraySlicePredicate.cpp +++ b/libsolidity/formal/ArraySlicePredicate.cpp @@ -18,6 +18,8 @@ #include +#include + #include using namespace solidity; diff --git a/libsolidity/formal/ArraySlicePredicate.h b/libsolidity/formal/ArraySlicePredicate.h index 180a9d1898ed..565dba657b9c 100644 --- a/libsolidity/formal/ArraySlicePredicate.h +++ b/libsolidity/formal/ArraySlicePredicate.h @@ -16,9 +16,9 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include +#pragma once + #include -#include #include diff --git a/libsolidity/formal/EncodingContext.cpp b/libsolidity/formal/EncodingContext.cpp index e0a09bcf7b8f..cc046cf0337d 100644 --- a/libsolidity/formal/EncodingContext.cpp +++ b/libsolidity/formal/EncodingContext.cpp @@ -18,12 +18,19 @@ #include +#include + #include using namespace solidity; using namespace solidity::util; using namespace solidity::frontend::smt; +bool EncodingContext::IdCompare::operator()(ASTNode const* lhs, ASTNode const* rhs) const +{ + return lhs->id() < rhs->id(); +} + EncodingContext::EncodingContext(): m_state(*this) { diff --git a/libsolidity/formal/EncodingContext.h b/libsolidity/formal/EncodingContext.h index 5387184ee0c9..e7d577bbf52c 100644 --- a/libsolidity/formal/EncodingContext.h +++ b/libsolidity/formal/EncodingContext.h @@ -68,10 +68,7 @@ class EncodingContext struct IdCompare { - bool operator()(ASTNode const* lhs, ASTNode const* rhs) const - { - return lhs->id() < rhs->id(); - } + bool operator()(ASTNode const* lhs, ASTNode const* rhs) const; }; /// Variables. diff --git a/libsolidity/formal/ExpressionFormatter.cpp b/libsolidity/formal/ExpressionFormatter.cpp index 865a568f62da..dff84c860aab 100644 --- a/libsolidity/formal/ExpressionFormatter.cpp +++ b/libsolidity/formal/ExpressionFormatter.cpp @@ -20,6 +20,8 @@ #include +#include + #include #include diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 66d8c2405538..7f742ec18d0b 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -28,7 +28,7 @@ #include -#include +#include #include using namespace solidity; diff --git a/libsolidity/formal/Predicate.h b/libsolidity/formal/Predicate.h index 7e4ba0f00fe8..d523f955404c 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -19,7 +19,8 @@ #pragma once -#include +#include +#include #include #include diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 738a48f706c3..11c92a83af40 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -20,6 +20,7 @@ #include +#include #include #include #include diff --git a/libsolidity/formal/SymbolicTypes.h b/libsolidity/formal/SymbolicTypes.h index d38dcc04514a..9259ff64a4c6 100644 --- a/libsolidity/formal/SymbolicTypes.h +++ b/libsolidity/formal/SymbolicTypes.h @@ -19,7 +19,6 @@ #pragma once #include -#include #include namespace solidity::frontend::smt diff --git a/libsolidity/formal/SymbolicVariables.cpp b/libsolidity/formal/SymbolicVariables.cpp index f0cebc46c291..29301d095ca4 100644 --- a/libsolidity/formal/SymbolicVariables.cpp +++ b/libsolidity/formal/SymbolicVariables.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include diff --git a/libsolidity/formal/VariableUsage.cpp b/libsolidity/formal/VariableUsage.cpp index ab7c425ae46c..000dcbc8175a 100644 --- a/libsolidity/formal/VariableUsage.cpp +++ b/libsolidity/formal/VariableUsage.cpp @@ -18,12 +18,9 @@ #include -#include #include -#include - -#include +#include using namespace solidity; using namespace solidity::util; From 629bb285394593aa5271d1a8dbdf335e71d99ce4 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sat, 29 Mar 2025 21:29:24 +0100 Subject: [PATCH 060/121] SMTChecker: Remove unused functionality --- libsolidity/CMakeLists.txt | 2 - libsolidity/formal/BMC.cpp | 1 - libsolidity/formal/SMTEncoder.cpp | 9 --- libsolidity/formal/SMTEncoder.h | 2 - libsolidity/formal/VariableUsage.cpp | 115 --------------------------- libsolidity/formal/VariableUsage.h | 65 --------------- 6 files changed, 194 deletions(-) delete mode 100644 libsolidity/formal/VariableUsage.cpp delete mode 100644 libsolidity/formal/VariableUsage.h diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index f0289acac3a8..62f0576dc59f 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -137,8 +137,6 @@ set(sources formal/SymbolicTypes.h formal/SymbolicVariables.cpp formal/SymbolicVariables.h - formal/VariableUsage.cpp - formal/VariableUsage.h formal/Z3CHCSmtLib2Interface.cpp formal/Z3CHCSmtLib2Interface.h formal/Z3SMTLib2Interface.cpp diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 8401c8dbfc0b..bcd88b6dac59 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -80,7 +80,6 @@ void BMC::analyze(SourceUnit const& _source, std::map SMTEncoder::touchedVariables(ASTNode const& _node) -{ - std::vector callStack; - for (auto const& call: m_callStack) - callStack.push_back(call.first); - return m_variableUsage.touchedVariables(_node, callStack); -} - Declaration const* SMTEncoder::expressionToDeclaration(Expression const& _expr) const { if (auto const* identifier = dynamic_cast(&_expr)) diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index 5bfb70d8126d..60cfb9cf90cd 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -454,7 +453,6 @@ class SMTEncoder: public ASTConstVisitor smtutil::Expression constraints; }; - smt::VariableUsage m_variableUsage; bool m_arrayAssignmentHappened = false; /// Stores the instances of an Uninterpreted Function applied to arguments. diff --git a/libsolidity/formal/VariableUsage.cpp b/libsolidity/formal/VariableUsage.cpp deleted file mode 100644 index 000dcbc8175a..000000000000 --- a/libsolidity/formal/VariableUsage.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include - -#include - -#include - -using namespace solidity; -using namespace solidity::util; -using namespace solidity::frontend; -using namespace solidity::frontend::smt; - -std::set VariableUsage::touchedVariables(ASTNode const& _node, std::vector const& _outerCallstack) -{ - m_touchedVariables.clear(); - m_callStack.clear(); - m_callStack += _outerCallstack; - if (!m_callStack.empty()) - m_lastCall = m_callStack.back(); - _node.accept(*this); - return m_touchedVariables; -} - -void VariableUsage::endVisit(Identifier const& _identifier) -{ - if (_identifier.annotation().willBeWrittenTo) - checkIdentifier(_identifier); -} - -void VariableUsage::endVisit(IndexAccess const& _indexAccess) -{ - if (_indexAccess.annotation().willBeWrittenTo) - { - /// identifier.annotation().willBeWrittenTo == false, that's why we - /// need to check that before. - auto identifier = dynamic_cast(SMTEncoder::leftmostBase(_indexAccess)); - if (identifier) - checkIdentifier(*identifier); - } -} - -void VariableUsage::endVisit(FunctionCall const& _funCall) -{ - auto scopeContract = currentScopeContract(); - if (m_inlineFunctionCalls(_funCall, scopeContract, m_currentContract)) - if (auto funDef = SMTEncoder::functionCallToDefinition(_funCall, scopeContract, m_currentContract)) - if (find(m_callStack.begin(), m_callStack.end(), funDef) == m_callStack.end()) - funDef->accept(*this); -} - -bool VariableUsage::visit(FunctionDefinition const& _function) -{ - m_callStack.push_back(&_function); - return true; -} - -void VariableUsage::endVisit(FunctionDefinition const&) -{ - solAssert(!m_callStack.empty(), ""); - m_callStack.pop_back(); -} - -void VariableUsage::endVisit(ModifierInvocation const& _modifierInv) -{ - auto const& modifierDef = dynamic_cast(_modifierInv.name().annotation().referencedDeclaration); - if (modifierDef) - modifierDef->accept(*this); -} - -void VariableUsage::endVisit(PlaceholderStatement const&) -{ - solAssert(!m_callStack.empty(), ""); - FunctionDefinition const* funDef = nullptr; - for (auto it = m_callStack.rbegin(); it != m_callStack.rend() && !funDef; ++it) - funDef = dynamic_cast(*it); - solAssert(funDef, ""); - if (funDef->isImplemented()) - funDef->body().accept(*this); -} - -void VariableUsage::checkIdentifier(Identifier const& _identifier) -{ - Declaration const* declaration = _identifier.annotation().referencedDeclaration; - solAssert(declaration, ""); - if (VariableDeclaration const* varDecl = dynamic_cast(declaration)) - { - if (!varDecl->isLocalVariable() || (m_lastCall && varDecl->functionOrModifierDefinition() == m_lastCall)) - m_touchedVariables.insert(varDecl); - } -} - -ContractDefinition const* VariableUsage::currentScopeContract() -{ - for (auto&& f: m_callStack | ranges::views::reverse) - if (auto fun = dynamic_cast(f)) - return fun->annotation().contract; - return nullptr; -} diff --git a/libsolidity/formal/VariableUsage.h b/libsolidity/formal/VariableUsage.h deleted file mode 100644 index 4dc90f8c07a7..000000000000 --- a/libsolidity/formal/VariableUsage.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#pragma once - -#include - -#include -#include - -namespace solidity::frontend::smt -{ - -/** - * This class computes information about which variables are modified in a certain subtree. - */ -class VariableUsage: private ASTConstVisitor -{ -public: - /// @param _outerCallstack the current callstack in the callers context. - std::set touchedVariables(ASTNode const& _node, std::vector const& _outerCallstack); - - /// Sets whether to inline function calls. - void setFunctionInlining(std::function _inlineFunctionCalls) { m_inlineFunctionCalls = _inlineFunctionCalls; } - - void setCurrentContract(ContractDefinition const& _contract) { m_currentContract = &_contract; } - -private: - void endVisit(Identifier const& _node) override; - void endVisit(IndexAccess const& _node) override; - void endVisit(FunctionCall const& _node) override; - bool visit(FunctionDefinition const& _node) override; - void endVisit(FunctionDefinition const& _node) override; - void endVisit(ModifierInvocation const& _node) override; - void endVisit(PlaceholderStatement const& _node) override; - - /// Checks whether an identifier should be added to touchedVariables. - void checkIdentifier(Identifier const& _identifier); - - ContractDefinition const* currentScopeContract(); - - std::set m_touchedVariables; - std::vector m_callStack; - CallableDeclaration const* m_lastCall = nullptr; - ContractDefinition const* m_currentContract = nullptr; - - std::function m_inlineFunctionCalls = [](FunctionCall const&, ContractDefinition const*, ContractDefinition const*) { return false; }; -}; - -} From ae3da8c12ec9f1f22c3e2e1a9b29e5896a8313cf Mon Sep 17 00:00:00 2001 From: Maxim Ryabykh Date: Wed, 2 Oct 2024 11:56:08 +0300 Subject: [PATCH 061/121] docs: fixed a mismatch in the name of the function referenced in the micropayment example --- docs/examples/micropayment.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index 9a3ad845ce1a..a7b26bb51b8b 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -274,8 +274,8 @@ Opening the Payment Channel To open the payment channel, Alice deploys the smart contract, attaching the Ether to be escrowed and specifying the intended recipient and a -maximum duration for the channel to exist. This is the function -``SimplePaymentChannel`` in the contract, at the end of this section. +maximum duration for the channel to exist. This is the ``constructor`` +in the ``SimplePaymentChannel`` contract, at the end of this section. Making Payments --------------- From fe7411114cc0c62ad386975a8ea491650b5c709a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 16 Apr 2025 13:37:43 +0200 Subject: [PATCH 062/121] EVMAssemblyStack: Add extra accessors that do not require contract name --- libevmasm/EVMAssemblyStack.cpp | 24 +++++++++++++++++------- libevmasm/EVMAssemblyStack.h | 6 ++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index 7cb05bf8bf00..bed4ff744ec4 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -74,13 +74,13 @@ void EVMAssemblyStack::assemble() LinkerObject const& EVMAssemblyStack::object(std::string const& _contractName) const { solAssert(_contractName == m_name); - return m_object; + return object(); } LinkerObject const& EVMAssemblyStack::runtimeObject(std::string const& _contractName) const { solAssert(_contractName == m_name); - return m_runtimeObject; + return runtimeObject(); } std::map EVMAssemblyStack::sourceIndices() const @@ -95,13 +95,13 @@ std::map EVMAssemblyStack::sourceIndices() const std::string const* EVMAssemblyStack::sourceMapping(std::string const& _contractName) const { solAssert(_contractName == m_name); - return &m_sourceMapping; + return &sourceMapping(); } std::string const* EVMAssemblyStack::runtimeSourceMapping(std::string const& _contractName) const { solAssert(_contractName == m_name); - return &m_runtimeSourceMapping; + return &runtimeSourceMapping(); } Json EVMAssemblyStack::ethdebug(std::string const& _contractName) const @@ -123,20 +123,30 @@ Json EVMAssemblyStack::ethdebug() const return {}; } -Json EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const +Json EVMAssemblyStack::assemblyJSON() const { - solAssert(_contractName == m_name); solAssert(m_evmAssembly); return m_evmAssembly->assemblyJSON(sourceIndices()); } -std::string EVMAssemblyStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const +Json EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const { solAssert(_contractName == m_name); + return assemblyJSON(); +} + +std::string EVMAssemblyStack::assemblyString(StringMap const& _sourceCodes) const +{ solAssert(m_evmAssembly); return m_evmAssembly->assemblyString(m_debugInfoSelection, _sourceCodes); } +std::string EVMAssemblyStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const +{ + solAssert(_contractName == m_name); + return assemblyString(_sourceCodes); +} + std::string const EVMAssemblyStack::filesystemFriendlyName(std::string const& _contractName) const { solAssert(_contractName == m_name); diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index 2fe63c11c2ec..444d444ba9e2 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -58,20 +58,26 @@ class EVMAssemblyStack: public AbstractAssemblyStack std::string const& name() const { return m_name; } + LinkerObject const& object() const { return m_object; } LinkerObject const& object(std::string const& _contractName) const override; + LinkerObject const& runtimeObject() const { return m_runtimeObject; } LinkerObject const& runtimeObject(std::string const& _contractName) const override; std::shared_ptr const& evmAssembly() const { return m_evmAssembly; } std::shared_ptr const& evmRuntimeAssembly() const { return m_evmRuntimeAssembly; } + std::string const& sourceMapping() const { return m_sourceMapping; } std::string const* sourceMapping(std::string const& _contractName) const override; + std::string const& runtimeSourceMapping() const { return m_runtimeSourceMapping; } std::string const* runtimeSourceMapping(std::string const& _contractName) const override; Json ethdebug(std::string const& _contractName) const override; Json ethdebugRuntime(std::string const& _contractName) const override; Json ethdebug() const override; + Json assemblyJSON() const; Json assemblyJSON(std::string const& _contractName) const override; + std::string assemblyString(StringMap const& _sourceCodes) const; std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override; std::string const filesystemFriendlyName(std::string const& _contractName) const override; From dd01ddda2379e6b9a2cf212e086e2d1ef6eb9340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 14 Mar 2025 04:04:14 +0100 Subject: [PATCH 063/121] TestCaseReader: Expose fileName() --- test/TestCaseReader.h | 1 + 1 file changed, 1 insertion(+) diff --git a/test/TestCaseReader.h b/test/TestCaseReader.h index d1ef95be3c2c..5830e97f3666 100644 --- a/test/TestCaseReader.h +++ b/test/TestCaseReader.h @@ -59,6 +59,7 @@ class TestCaseReader std::size_t lineNumber() const { return m_lineNumber; } std::map const& settings() const { return m_settings; } std::ifstream& stream() { return m_fileStream; } + boost::filesystem::path const& fileName() const { return m_fileName; } std::string simpleExpectations(); From d3238c08ff61516a6d86a3035a0582aaeb5e5894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 19 Apr 2025 04:36:11 +0200 Subject: [PATCH 064/121] Add a transparent comparator to c_instructions to allow string_view lookups --- libevmasm/Instruction.cpp | 2 +- libevmasm/Instruction.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index dad9804d09a8..b5568763573a 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -26,7 +26,7 @@ using namespace solidity; using namespace solidity::util; using namespace solidity::evmasm; -std::map const solidity::evmasm::c_instructions = +std::map> const solidity::evmasm::c_instructions = { { "STOP", Instruction::STOP }, { "ADD", Instruction::ADD }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 137144715296..cfdb85d2fa4c 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -322,6 +322,6 @@ InstructionInfo instructionInfo(Instruction _inst, langutil::EVMVersion _evmVers bool isValidInstruction(Instruction _inst); /// Convert from string mnemonic to Instruction type. -extern const std::map c_instructions; +extern const std::map> c_instructions; } From 266c7d49a8b9a9524d841b088410957bb7335e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 14 Mar 2025 04:51:35 +0100 Subject: [PATCH 065/121] EVM assembly test case with JSON input --- test/CMakeLists.txt | 2 + test/InteractiveTests.h | 3 + test/TestCase.cpp | 7 +- test/libevmasm/EVMAssemblyTest.cpp | 158 ++++++++++++++++++ test/libevmasm/EVMAssemblyTest.h | 70 ++++++++ .../code_generation_error.asmjson | 14 ++ .../isoltestTesting/invalid_json.asmjson | 3 + .../settings_eof_version.asmjson | 13 ++ .../settings_evm_version.asmjson | 13 ++ ...tings_optimizer_constant_optimizer.asmjson | 14 ++ .../settings_optimizer_cse.asmjson | 16 ++ .../settings_optimizer_deduplicate.asmjson | 26 +++ ...expected_executions_per_deployment.asmjson | 26 +++ .../settings_optimizer_inliner.asmjson | 33 ++++ ...ettings_optimizer_jumpdest_remover.asmjson | 14 ++ .../settings_optimizer_peephole.asmjson | 15 ++ .../settings_optimizer_preset.asmjson | 18 ++ .../isoltestTesting/settings_outputs.asmjson | 10 ++ .../isoltestTesting/smoke.asmjson | 11 ++ test/tools/CMakeLists.txt | 1 + test/tools/isoltest.cpp | 2 +- 21 files changed, 465 insertions(+), 4 deletions(-) create mode 100644 test/libevmasm/EVMAssemblyTest.cpp create mode 100644 test/libevmasm/EVMAssemblyTest.h create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index da115f0d4a5b..6f48b8a8469e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -51,6 +51,8 @@ detect_stray_source_files("${libsolutil_sources}" "libsolutil/") set(libevmasm_sources libevmasm/Assembler.cpp + libevmasm/EVMAssemblyTest.cpp + libevmasm/EVMAssemblyTest.h libevmasm/Optimiser.cpp ) detect_stray_source_files("${libevmasm_sources}" "libevmasm/") diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index e043fcdbe676..107a6aae0bef 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -42,6 +42,8 @@ #include #include +#include + #include namespace solidity::frontend::test @@ -64,6 +66,7 @@ struct Testsuite Testsuite const g_interactiveTestsuites[] = { /* Title Path Subpath SMT NeedsVM Creator function */ + {"EVM Assembly", "libevmasm", "evmAssemblyTests", false, false, &evmasm::test::EVMAssemblyTest::create}, {"Yul Optimizer", "libyul", "yulOptimizerTests", false, false, &yul::test::YulOptimizerTest::create}, {"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create}, {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, diff --git a/test/TestCase.cpp b/test/TestCase.cpp index da47c26fde90..8a8d2451d1f2 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -51,9 +51,10 @@ void TestCase::printUpdatedSettings(std::ostream& _stream, std::string const& _l bool TestCase::isTestFilename(boost::filesystem::path const& _filename) { std::string extension = _filename.extension().string(); - return (extension == ".sol" || extension == ".yul" || extension == ".stack") && - !boost::starts_with(_filename.string(), "~") && - !boost::starts_with(_filename.string(), "."); + // NOTE: .asmjson rather than .json because JSON files that do not represent test cases exist in some test dirs. + return (extension == ".sol" || extension == ".yul" || extension == ".asmjson" || extension == ".stack") && + !_filename.string().starts_with('~') && + !_filename.string().starts_with('.'); } bool TestCase::shouldRun() diff --git a/test/libevmasm/EVMAssemblyTest.cpp b/test/libevmasm/EVMAssemblyTest.cpp new file mode 100644 index 000000000000..b497c51476e6 --- /dev/null +++ b/test/libevmasm/EVMAssemblyTest.cpp @@ -0,0 +1,158 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +using namespace std::string_literals; +using namespace solidity; +using namespace solidity::test; +using namespace solidity::evmasm; +using namespace solidity::evmasm::test; +using namespace solidity::frontend; +using namespace solidity::frontend::test; +using namespace solidity::langutil; +using namespace solidity::util; + +std::vector const EVMAssemblyTest::c_outputLabels = { + "Assembly", + "Bytecode", + "Opcodes", + "SourceMappings", +}; + +std::unique_ptr EVMAssemblyTest::create(Config const& _config) +{ + return std::make_unique(_config.filename); +} + +EVMAssemblyTest::EVMAssemblyTest(std::string const& _filename): + EVMVersionRestrictedTestCase(_filename) +{ + m_source = m_reader.source(); + m_expectation = m_reader.simpleExpectations(); + + if (!_filename.ends_with(".asmjson")) + BOOST_THROW_EXCEPTION(std::runtime_error("Not an assembly test: \"" + _filename + "\". Allowed extensions: .asmjson.")); + + m_selectedOutputs = m_reader.stringSetting("outputs", "Assembly,Bytecode,Opcodes,SourceMappings"); + OptimisationPreset optimizationPreset = m_reader.enumSetting( + "optimizationPreset", + { + {"none", OptimisationPreset::None}, + {"minimal", OptimisationPreset::Minimal}, + {"standard", OptimisationPreset::Standard}, + {"full", OptimisationPreset::Full}, + }, + "none" + ); + m_optimizerSettings = Assembly::OptimiserSettings::translateSettings(OptimiserSettings::preset(optimizationPreset)); + m_optimizerSettings.expectedExecutionsPerDeployment = m_reader.sizetSetting( + "optimizer.expectedExecutionsPerDeployment", + m_optimizerSettings.expectedExecutionsPerDeployment + ); + + auto const optimizerComponentSetting = [&](std::string const& _component, bool& _setting) { + _setting = m_reader.boolSetting("optimizer." + _component, _setting); + }; + optimizerComponentSetting("inliner", m_optimizerSettings.runInliner); + optimizerComponentSetting("jumpdestRemover", m_optimizerSettings.runJumpdestRemover); + optimizerComponentSetting("peephole", m_optimizerSettings.runPeephole); + optimizerComponentSetting("deduplicate", m_optimizerSettings.runDeduplicate); + optimizerComponentSetting("cse", m_optimizerSettings.runCSE); + optimizerComponentSetting("constantOptimizer", m_optimizerSettings.runConstantOptimiser); + + // TODO: Enable when assembly import for EOF is implemented. + if (CommonOptions::get().eofVersion().has_value()) + m_shouldRun = false; +} + +TestCase::TestResult EVMAssemblyTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) +{ + EVMAssemblyStack evmAssemblyStack( + CommonOptions::get().evmVersion(), + CommonOptions::get().eofVersion(), + m_optimizerSettings + ); + + evmAssemblyStack.selectDebugInfo(DebugInfoSelection::AllExceptExperimental()); + + try + { + evmAssemblyStack.parseAndAnalyze(m_reader.fileName().filename().string(), m_source); + } + catch (AssemblyImportException const& _exception) + { + m_obtainedResult = "AssemblyImportException: "s + _exception.what() + "\n"; + return checkResult(_stream, _linePrefix, _formatted); + } + + try + { + evmAssemblyStack.assemble(); + } + catch (Error const& _error) + { + // TODO: EVMAssemblyStack should catch these on its own and provide an error reporter. + soltestAssert(_error.comment(), "Errors must include a message for the user."); + m_obtainedResult = Error::formatErrorType(_error.type()) + ": " + *_error.comment() + "\n"; + return checkResult(_stream, _linePrefix, _formatted); + } + soltestAssert(evmAssemblyStack.compilationSuccessful()); + + auto const produceOutput = [&](std::string const& _output) { + if (_output == "Assembly") + return evmAssemblyStack.assemblyString({{m_reader.fileName().filename().string(), m_source}}); + if (_output == "Bytecode") + return util::toHex(evmAssemblyStack.object().bytecode); + if (_output == "Opcodes") + return disassemble(evmAssemblyStack.object().bytecode, CommonOptions::get().evmVersion()); + if (_output == "SourceMappings") + return evmAssemblyStack.sourceMapping(); + soltestAssert(false); + unreachable(); + }; + + std::set selectedOutputSet; + boost::split(selectedOutputSet, m_selectedOutputs, boost::is_any_of(",")); + for (std::string const& output: c_outputLabels) + if (selectedOutputSet.contains(output)) + { + if (!m_obtainedResult.empty() && m_obtainedResult.back() != '\n') + m_obtainedResult += "\n"; + + // Don't trim on the left to avoid stripping indentation. + std::string content = produceOutput(output); + boost::trim_right(content); + std::string separator = (content.empty() ? "" : (output == "Assembly" ? "\n" : " ")); + m_obtainedResult += output + ":" + separator + content; + } + if (!m_obtainedResult.empty() && m_obtainedResult.back() != '\n') + m_obtainedResult += "\n"; + + return checkResult(_stream, _linePrefix, _formatted); +} diff --git a/test/libevmasm/EVMAssemblyTest.h b/test/libevmasm/EVMAssemblyTest.h new file mode 100644 index 000000000000..f8923c0dc1a1 --- /dev/null +++ b/test/libevmasm/EVMAssemblyTest.h @@ -0,0 +1,70 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include + +#include +#include +#include +#include + +namespace solidity::evmasm::test +{ + +/// Custom test case that runs the final part of the compiler pipeline (assembling into bytecode). +/// Supports assembly JSON format produced by --asm-json. +/// +/// Available settings: +/// - EVMVersion: The range of EVM versions to run the test for. Inherited from EVMVersionRestrictedTestCase. +/// - bytecodeFormat: The range of bytecode formats (EOF/legacy) to run the test for. Inherited from EVMVersionRestrictedTestCase. +/// - outputs: List of outputs to include in the test. The order of values does NOT determine the order +/// in which the outputs are printed. Supported outputs: Assembly, Bytecode, Opcodes, SourceMappings. +/// The default is to print all outputs. +/// - optimizationPreset: Preset to load as the base optimizer settings. +/// One of: none, minimal, standard, full. The default is none. +/// - optimizer.*: A set of detailed optimizer settings applied on top of the base preset. +/// Each one corresponds to a field in Assembly::OptimiserSettings and uses the value from the +/// preset as its default. Available settings: +/// - optimizer.expectedExecutionsPerDeployment (integer) +/// - optimizer.inliner (bool) +/// - optimizer.jumpdestRemover (bool) +/// - optimizer.peephole (bool) +/// - optimizer.deduplicate (bool) +/// - optimizer.cse (bool) +/// - optimizer.constantOptimizer (bool) +class EVMAssemblyTest: public frontend::test::EVMVersionRestrictedTestCase +{ +public: + static std::unique_ptr create(Config const& _config); + + EVMAssemblyTest(std::string const& _filename); + + TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; + +private: + static std::vector const c_outputLabels; + + std::string m_selectedOutputs; + evmasm::Assembly::OptimiserSettings m_optimizerSettings; +}; + +} diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson new file mode 100644 index 000000000000..4297c5f35b80 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson @@ -0,0 +1,14 @@ +{ + ".code": [ + {"name": "PUSH [$]", "value": "0"} + ], + ".data": { + "0": { + ".code": [ + {"name": "PUSHIMMUTABLE", "value": "x"} + ] + } + } +} +// ---- +// CodeGenerationError: Some immutables were read from but never assigned, possibly because of optimization. diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson new file mode 100644 index 000000000000..a834108d1ad7 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson @@ -0,0 +1,3 @@ +{ +// ---- +// AssemblyImportException: Could not parse JSON file. diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson new file mode 100644 index 000000000000..5785b4b8931e --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson @@ -0,0 +1,13 @@ +{ + ".code": [ + {"name": "CODESIZE"} + ] +} +// ==== +// bytecodeFormat: legacy +// ---- +// Assembly: +// codesize +// Bytecode: 38 +// Opcodes: CODESIZE +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson new file mode 100644 index 000000000000..a0f042b32e88 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson @@ -0,0 +1,13 @@ +{ + ".code": [ + {"name": "BLOBBASEFEE"} + ] +} +// ==== +// EVMVersion: >=cancun +// ---- +// Assembly: +// blobbasefee +// Bytecode: 4a +// Opcodes: BLOBBASEFEE +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson new file mode 100644 index 000000000000..a3610217fbaf --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson @@ -0,0 +1,14 @@ +{ + ".code": [ + {"name": "PUSH", "value": "ffffffffffffffff"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.constantOptimizer: true +// ---- +// Assembly: +// sub(shl(0x40, 0x01), 0x01) +// Bytecode: 6001600160401b03 +// Opcodes: PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB +// SourceMappings: :::-:0;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson new file mode 100644 index 000000000000..c8133b43f799 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson @@ -0,0 +1,16 @@ +{ + ".code": [ + {"name": "PUSH", "value": "0"}, + {"name": "DUP2"}, + {"name": "SUB"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.cse: true +// ---- +// Assembly: +// dup1 +// Bytecode: 80 +// Opcodes: DUP1 +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson new file mode 100644 index 000000000000..67b87e59e9ee --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson @@ -0,0 +1,26 @@ +{ + ".code": [ + {"name": "PUSH [tag]", "value": "1"}, + {"name": "PUSH [tag]", "value": "2"}, + {"name": "tag", "value": "1"}, + {"name": "JUMPDEST"}, + {"name": "JUMP"}, + {"name": "tag", "value": "2"}, + {"name": "JUMPDEST"}, + {"name": "JUMP"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.deduplicate: true +// ---- +// Assembly: +// tag_1 +// tag_1 +// tag_1: +// jump +// tag_2: +// jump +// Bytecode: 600460045b565b56 +// Opcodes: PUSH1 0x4 PUSH1 0x4 JUMPDEST JUMP JUMPDEST JUMP +// SourceMappings: :::-:0;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson new file mode 100644 index 000000000000..b9fd814d5c8e --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson @@ -0,0 +1,26 @@ +{ + ".code": [ + {"name": "PUSH [$]", "value": "0"} + ], + ".data": { + "0": { + ".code": [ + {"name": "PUSH", "value": "ffffffffffffffff"} + ] + } + } +} +// ==== +// optimizationPreset: standard +// optimizer.expectedExecutionsPerDeployment: 0 +// ---- +// Assembly: +// dataOffset(sub_0) +// stop +// +// sub_0: assembly { +// sub(shl(0x40, 0x01), 0x01) +// } +// Bytecode: 6003fe6001600160401b03 +// Opcodes: PUSH1 0x3 INVALID PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson new file mode 100644 index 000000000000..81be6392c444 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson @@ -0,0 +1,33 @@ +{ + ".code": [ + {"name": "PUSH [tag]", "value": "1"}, + {"name": "PUSH [tag]", "value": "2"}, + {"name": "JUMP"}, + {"name": "tag", "value": "1"}, + {"name": "JUMPDEST"}, + {"name": "STOP"}, + {"name": "tag", "value": "2"}, + {"name": "JUMPDEST"}, + {"name": "CALLVALUE"}, + {"name": "SWAP1"}, + {"name": "JUMP"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.inliner: true +// ---- +// Assembly: +// tag_1 +// callvalue +// swap1 +// jump +// tag_1: +// stop +// tag_2: +// callvalue +// swap1 +// jump +// Bytecode: 60053490565b005b349056 +// Opcodes: PUSH1 0x5 CALLVALUE SWAP1 JUMP JUMPDEST STOP JUMPDEST CALLVALUE SWAP1 JUMP +// SourceMappings: :::-:0;;;;;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson new file mode 100644 index 000000000000..baca77b992fc --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson @@ -0,0 +1,14 @@ +{ + ".code": [ + {"name": "tag", "value": "1"}, + {"name": "JUMPDEST"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.jumpdestRemover: true +// ---- +// Assembly: +// Bytecode: +// Opcodes: +// SourceMappings: diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson new file mode 100644 index 000000000000..f9e7c3b8d550 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson @@ -0,0 +1,15 @@ +{ + ".code": [ + {"name": "STOP"}, + {"name": "STOP"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.peephole: true +// ---- +// Assembly: +// stop +// Bytecode: 00 +// Opcodes: STOP +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson new file mode 100644 index 000000000000..706a3ae8b61a --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson @@ -0,0 +1,18 @@ +{ + ".code": [ + {"name": "PUSH", "value": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"name": "PUSH", "value": "42"}, + {"name": "PUSH", "value": "24"}, + {"name": "SWAP1"}, + {"name": "ADD"} + ] +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// not(0x00) +// 0x66 +// Bytecode: 5f196066 +// Opcodes: PUSH0 NOT PUSH1 0x66 +// SourceMappings: :::-:0;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson new file mode 100644 index 000000000000..2af7b57c3e75 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson @@ -0,0 +1,10 @@ +{ + ".code": [ + {"name": "CALLVALUE"} + ] +} +// ==== +// outputs: SourceMappings,Opcodes +// ---- +// Opcodes: CALLVALUE +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson new file mode 100644 index 000000000000..99e527a72587 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson @@ -0,0 +1,11 @@ +{ + ".code": [ + {"name": "CALLVALUE"} + ] +} +// ---- +// Assembly: +// callvalue +// Bytecode: 34 +// Opcodes: CALLVALUE +// SourceMappings: :::-:0 diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 5c1d41b7f595..13018bf18512 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable(isoltest ../EVMHost.cpp ../TestCase.cpp ../TestCaseReader.cpp + ../libevmasm/EVMAssemblyTest.cpp ../libsolidity/util/BytesUtils.cpp ../libsolidity/util/Common.cpp ../libsolidity/util/ContractABIUtils.cpp diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 57ab4af16034..32309b005507 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -75,7 +75,7 @@ class TestFilter boost::replace_all(filter, "/", "\\/"); boost::replace_all(filter, "*", ".*"); - m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.stack))"}; + m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.asmjson|\\.stack))"}; } bool matches(fs::path const& _path, std::string const& _name) const From fe3955111883851f64939783b9f542ccf33f6998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 18 Apr 2025 03:18:05 +0200 Subject: [PATCH 066/121] Support human-readable assembly in EVM assembly test case --- test/CMakeLists.txt | 2 + test/TestCase.cpp | 2 +- test/libevmasm/EVMAssemblyTest.cpp | 29 ++- test/libevmasm/EVMAssemblyTest.h | 16 +- test/libevmasm/PlainAssemblyParser.cpp | 180 ++++++++++++++++++ test/libevmasm/PlainAssemblyParser.h | 79 ++++++++ .../isoltestTesting/comments.asm | 34 ++++ .../isoltestTesting/jumps.asm | 56 ++++++ .../isoltestTesting/operations.asm | 53 ++++++ .../evmAssemblyTests/isoltestTesting/push.asm | 35 ++++ .../isoltestTesting/smoke_plain.asm | 16 ++ test/tools/CMakeLists.txt | 1 + test/tools/isoltest.cpp | 2 +- 13 files changed, 497 insertions(+), 8 deletions(-) create mode 100644 test/libevmasm/PlainAssemblyParser.cpp create mode 100644 test/libevmasm/PlainAssemblyParser.h create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6f48b8a8469e..c66963c190d4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -54,6 +54,8 @@ set(libevmasm_sources libevmasm/EVMAssemblyTest.cpp libevmasm/EVMAssemblyTest.h libevmasm/Optimiser.cpp + libevmasm/PlainAssemblyParser.cpp + libevmasm/PlainAssemblyParser.h ) detect_stray_source_files("${libevmasm_sources}" "libevmasm/") diff --git a/test/TestCase.cpp b/test/TestCase.cpp index 8a8d2451d1f2..efc455ff6ff1 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -52,7 +52,7 @@ bool TestCase::isTestFilename(boost::filesystem::path const& _filename) { std::string extension = _filename.extension().string(); // NOTE: .asmjson rather than .json because JSON files that do not represent test cases exist in some test dirs. - return (extension == ".sol" || extension == ".yul" || extension == ".asmjson" || extension == ".stack") && + return (extension == ".sol" || extension == ".yul" || extension == ".asm" || extension == ".asmjson" || extension == ".stack") && !_filename.string().starts_with('~') && !_filename.string().starts_with('.'); } diff --git a/test/libevmasm/EVMAssemblyTest.cpp b/test/libevmasm/EVMAssemblyTest.cpp index b497c51476e6..0c1dbb07ed7c 100644 --- a/test/libevmasm/EVMAssemblyTest.cpp +++ b/test/libevmasm/EVMAssemblyTest.cpp @@ -17,6 +17,8 @@ #include +#include + #include #include @@ -39,6 +41,7 @@ using namespace solidity::langutil; using namespace solidity::util; std::vector const EVMAssemblyTest::c_outputLabels = { + "InputAssemblyJSON", "Assembly", "Bytecode", "Opcodes", @@ -56,8 +59,12 @@ EVMAssemblyTest::EVMAssemblyTest(std::string const& _filename): m_source = m_reader.source(); m_expectation = m_reader.simpleExpectations(); - if (!_filename.ends_with(".asmjson")) - BOOST_THROW_EXCEPTION(std::runtime_error("Not an assembly test: \"" + _filename + "\". Allowed extensions: .asmjson.")); + if (_filename.ends_with(".asmjson")) + m_assemblyFormat = AssemblyFormat::JSON; + else if (_filename.ends_with(".asm")) + m_assemblyFormat = AssemblyFormat::Plain; + else + BOOST_THROW_EXCEPTION(std::runtime_error("Not an assembly test: \"" + _filename + "\". Allowed extensions: .asm, .asmjson.")); m_selectedOutputs = m_reader.stringSetting("outputs", "Assembly,Bytecode,Opcodes,SourceMappings"); OptimisationPreset optimizationPreset = m_reader.enumSetting( @@ -101,9 +108,23 @@ TestCase::TestResult EVMAssemblyTest::run(std::ostream& _stream, std::string con evmAssemblyStack.selectDebugInfo(DebugInfoSelection::AllExceptExperimental()); + std::string assemblyJSON; + switch (m_assemblyFormat) + { + case AssemblyFormat::JSON: + assemblyJSON = m_source; + break; + case AssemblyFormat::Plain: + assemblyJSON = jsonPrint( + PlainAssemblyParser{}.parse(m_reader.fileName().filename().string(), m_source), + {JsonFormat::Pretty, 4} + ); + break; + } + try { - evmAssemblyStack.parseAndAnalyze(m_reader.fileName().filename().string(), m_source); + evmAssemblyStack.parseAndAnalyze(m_reader.fileName().filename().string(), assemblyJSON); } catch (AssemblyImportException const& _exception) { @@ -125,6 +146,8 @@ TestCase::TestResult EVMAssemblyTest::run(std::ostream& _stream, std::string con soltestAssert(evmAssemblyStack.compilationSuccessful()); auto const produceOutput = [&](std::string const& _output) { + if (_output == "InputAssemblyJSON") + return assemblyJSON; if (_output == "Assembly") return evmAssemblyStack.assemblyString({{m_reader.fileName().filename().string(), m_source}}); if (_output == "Bytecode") diff --git a/test/libevmasm/EVMAssemblyTest.h b/test/libevmasm/EVMAssemblyTest.h index f8923c0dc1a1..9059fd716d81 100644 --- a/test/libevmasm/EVMAssemblyTest.h +++ b/test/libevmasm/EVMAssemblyTest.h @@ -31,14 +31,17 @@ namespace solidity::evmasm::test { /// Custom test case that runs the final part of the compiler pipeline (assembling into bytecode). -/// Supports assembly JSON format produced by --asm-json. +/// Supports two kinds of input (depending on file extension): +/// - .asmjson: assembly JSON format produced by --asm-json. +/// - .asm: plain assembly, a more limited but human-readable format that is internally converted +/// to assembly JSON. /// /// Available settings: /// - EVMVersion: The range of EVM versions to run the test for. Inherited from EVMVersionRestrictedTestCase. /// - bytecodeFormat: The range of bytecode formats (EOF/legacy) to run the test for. Inherited from EVMVersionRestrictedTestCase. /// - outputs: List of outputs to include in the test. The order of values does NOT determine the order -/// in which the outputs are printed. Supported outputs: Assembly, Bytecode, Opcodes, SourceMappings. -/// The default is to print all outputs. +/// in which the outputs are printed. Supported outputs: InputAssemblyJSON, Assembly, Bytecode, Opcodes, SourceMappings. +/// The default is to print all outputs except InputAssemblyJSON. /// - optimizationPreset: Preset to load as the base optimizer settings. /// One of: none, minimal, standard, full. The default is none. /// - optimizer.*: A set of detailed optimizer settings applied on top of the base preset. @@ -61,8 +64,15 @@ class EVMAssemblyTest: public frontend::test::EVMVersionRestrictedTestCase TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; private: + enum class AssemblyFormat + { + JSON, + Plain, + }; + static std::vector const c_outputLabels; + AssemblyFormat m_assemblyFormat{}; std::string m_selectedOutputs; evmasm::Assembly::OptimiserSettings m_optimizerSettings; }; diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp new file mode 100644 index 000000000000..0fb9d62c8c10 --- /dev/null +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -0,0 +1,180 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#include + +#include +#include + +#include + +#include + +#include + +#include + +#include + +using namespace std::string_literals; +using namespace solidity; +using namespace solidity::test; +using namespace solidity::evmasm; +using namespace solidity::evmasm::test; +using namespace solidity::langutil; + +Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _source) +{ + m_sourceName = std::move(_sourceName); + Json codeJSON = Json::array(); + std::istringstream sourceStream(_source); + while (getline(sourceStream, m_line)) + { + advanceLine(m_line); + if (m_lineTokens.empty()) + continue; + + if (c_instructions.contains(currentToken().value)) + { + expectNoMoreArguments(); + codeJSON.push_back({{"name", currentToken().value}}); + } + else if (currentToken().value == "PUSH") + { + if (hasMoreTokens() && nextToken().value == "[tag]") + { + advanceToken(); + std::string_view tagID = expectArgument(); + expectNoMoreArguments(); + codeJSON.push_back({{"name", "PUSH [tag]"}, {"value", tagID}}); + } + else + { + std::string_view immediateArgument = expectArgument(); + expectNoMoreArguments(); + + if (!immediateArgument.starts_with("0x")) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The immediate argument to PUSH must be a hex number prefixed with '0x'."))); + + immediateArgument.remove_prefix("0x"s.size()); + codeJSON.push_back({{"name", "PUSH"}, {"value", immediateArgument}}); + } + } + else if (currentToken().value == "tag") + { + std::string_view tagID = expectArgument(); + expectNoMoreArguments(); + + codeJSON.push_back({{"name", "tag"}, {"value", tagID}}); + codeJSON.push_back({{"name", "JUMPDEST"}}); + } + else + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Unknown instruction."))); + } + return {{".code", codeJSON}}; +} + +PlainAssemblyParser::Token const& PlainAssemblyParser::currentToken() const +{ + soltestAssert(m_tokenIndex < m_lineTokens.size()); + return m_lineTokens[m_tokenIndex]; +} + +PlainAssemblyParser::Token const& PlainAssemblyParser::nextToken() const +{ + soltestAssert(m_tokenIndex + 1 < m_lineTokens.size()); + return m_lineTokens[m_tokenIndex + 1]; +} + +bool PlainAssemblyParser::advanceToken() +{ + if (!hasMoreTokens()) + return false; + + ++m_tokenIndex; + return true; +} + +std::string_view PlainAssemblyParser::expectArgument() +{ + bool hasArgument = advanceToken(); + if (!hasArgument) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Missing argument(s)."))); + + return currentToken().value; +} + +void PlainAssemblyParser::expectNoMoreArguments() +{ + bool hasArgument = advanceToken(); + if (hasArgument) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Too many arguments."))); +} + +void PlainAssemblyParser::advanceLine(std::string_view _line) +{ + ++m_lineNumber; + m_line = _line; + m_lineTokens = tokenizeLine(m_line); + m_tokenIndex = 0; +} + +std::vector PlainAssemblyParser::tokenizeLine(std::string_view _line) +{ + auto const notWhiteSpace = [](char _c) { return !isWhiteSpace(_c); }; + + std::vector tokens; + auto tokenLocation = boost::find_token(_line, notWhiteSpace, boost::token_compress_on); + while (!tokenLocation.empty()) + { + std::string_view value{tokenLocation.begin(), tokenLocation.end()}; + if (value.starts_with("//")) + break; + + tokens.push_back({ + .value = value, + .position = static_cast(std::distance(_line.begin(), tokenLocation.begin())), + }); + soltestAssert(!value.empty()); + soltestAssert(tokens.back().position < _line.size()); + soltestAssert(tokens.back().position + value.size() <= _line.size()); + + std::string_view tail{tokenLocation.end(), _line.end()}; + tokenLocation = boost::find_token(tail, notWhiteSpace, boost::token_compress_on); + } + + return tokens; +} + +std::string PlainAssemblyParser::formatError(std::string_view _message) const +{ + std::string lineNumberString = std::to_string(m_lineNumber); + std::string padding(lineNumberString.size(), ' '); + std::string underline = std::string(currentToken().position, ' ') + std::string(currentToken().value.size(), '^'); + return fmt::format( + "Error while parsing plain assembly: {}\n" + "{}--> {}\n" + "{} | \n" + "{} | {}\n" + "{} | {}\n", + _message, + padding, m_sourceName, + padding, + m_lineNumber, m_line, + padding, underline + ); +} diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h new file mode 100644 index 000000000000..0154af5f7f19 --- /dev/null +++ b/test/libevmasm/PlainAssemblyParser.h @@ -0,0 +1,79 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include +#include + +namespace solidity::evmasm::test +{ + +/// Parser for the plain assembly format. The format is meant to be good enough for humans to read +/// while being straightforward to map to the assembly JSON format that solc can import. +/// +/// Syntax: +/// - Every line consists of zero or more whitespace-separated tokens. +/// - A token that begins with `//` starts a comment, which extends to the end of the line. +/// - A non-empty line represents a single assembly item. +/// - The name of the item is the first thing on the line and may consist of one or more tokens. +/// - One or more arguments follow the name. +/// +/// Supported items: +/// - All instruction names. +/// - PUSH +/// - PUSH [tag] +/// - tag +class PlainAssemblyParser +{ +public: + /// Parses plain assembly format and returns the equivalent assembly JSON. + /// Errors are reported by throwing runtime_error. + Json parse(std::string _sourceName, std::string const& _source); + +protected: + struct Token + { + std::string_view value; ///< Substring of m_line that represents a complete token. + size_t position; ///< Position of the first character of the token within m_line. + }; + + Token const& currentToken() const; + Token const& nextToken() const; + bool hasMoreTokens() const { return m_tokenIndex + 1 < m_lineTokens.size(); } + + bool advanceToken(); + std::string_view expectArgument(); + void expectNoMoreArguments(); + void advanceLine(std::string_view _line); + + static std::vector tokenizeLine(std::string_view _line); + std::string formatError(std::string_view _message) const; + +private: + std::string m_sourceName; ///< Name of the file the source comes from. + size_t m_lineNumber = 0; ///< The number of the current line within the source, 1-based. + std::string m_line; ///< The current line, unparsed. + std::vector m_lineTokens; ///< Decomposition of the current line into tokens (does not include comments). + size_t m_tokenIndex = 0; ///< Points at a token within m_lineTokens. +}; + +} diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm new file mode 100644 index 000000000000..13dca3ad1b2f --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm @@ -0,0 +1,34 @@ +// +//// comment + // comment +CALLVALUE // 0xff +CALLVALUE //0xff + +PUSH 0xff // comment // //0xff +// + +// +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "CALLVALUE" +// }, +// { +// "name": "CALLVALUE" +// }, +// { +// "name": "PUSH", +// "value": "ff" +// } +// ] +// } +// Assembly: +// callvalue +// callvalue +// 0xff +// Bytecode: 343460ff +// Opcodes: CALLVALUE CALLVALUE PUSH1 0xFF +// SourceMappings: :::-:0;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm new file mode 100644 index 000000000000..be92671d8141 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm @@ -0,0 +1,56 @@ +PUSH [tag] 1 +JUMP +tag 1 +PUSH 0x01 +JUMPI +PUSH [tag] 0x012AB +tag 0x012AB +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH [tag]", +// "value": "1" +// }, +// { +// "name": "JUMP" +// }, +// { +// "name": "tag", +// "value": "1" +// }, +// { +// "name": "JUMPDEST" +// }, +// { +// "name": "PUSH", +// "value": "01" +// }, +// { +// "name": "JUMPI" +// }, +// { +// "name": "PUSH [tag]", +// "value": "0x012AB" +// }, +// { +// "name": "tag", +// "value": "0x012AB" +// }, +// { +// "name": "JUMPDEST" +// } +// ] +// } +// Assembly: +// jump(tag_1) +// tag_1: +// 0x01 +// jumpi +// tag_4779 +// tag_4779: +// Bytecode: 6003565b60015760095b +// Opcodes: PUSH1 0x3 JUMP JUMPDEST PUSH1 0x1 JUMPI PUSH1 0x9 JUMPDEST +// SourceMappings: :::-:0;;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm new file mode 100644 index 000000000000..923b0a6b1f37 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm @@ -0,0 +1,53 @@ +NUMBER +SLOAD +ADDRESS +ORIGIN +ADD +DUP1 +SWAP1 +MSTORE8 +STOP +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "SLOAD" +// }, +// { +// "name": "ADDRESS" +// }, +// { +// "name": "ORIGIN" +// }, +// { +// "name": "ADD" +// }, +// { +// "name": "DUP1" +// }, +// { +// "name": "SWAP1" +// }, +// { +// "name": "MSTORE8" +// }, +// { +// "name": "STOP" +// } +// ] +// } +// Assembly: +// sload(number) +// add(origin, address) +// dup1 +// swap1 +// mstore8 +// stop +// Bytecode: 435430320180905300 +// Opcodes: NUMBER SLOAD ADDRESS ORIGIN ADD DUP1 SWAP1 MSTORE8 STOP +// SourceMappings: :::-:0;;;;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm new file mode 100644 index 000000000000..51bc160507c7 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm @@ -0,0 +1,35 @@ +PUSH 0x0 +PUSH 0x1 +PUSH 0x0123456789ABCDEF +PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH", +// "value": "0" +// }, +// { +// "name": "PUSH", +// "value": "1" +// }, +// { +// "name": "PUSH", +// "value": "0123456789ABCDEF" +// }, +// { +// "name": "PUSH", +// "value": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +// } +// ] +// } +// Assembly: +// 0x00 +// 0x01 +// 0x0123456789abcdef +// 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// Bytecode: 5f6001670123456789abcdef7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// Opcodes: PUSH0 PUSH1 0x1 PUSH8 0x123456789ABCDEF PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// SourceMappings: :::-:0;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm new file mode 100644 index 000000000000..a1714241fb86 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm @@ -0,0 +1,16 @@ +CALLVALUE +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "CALLVALUE" +// } +// ] +// } +// Assembly: +// callvalue +// Bytecode: 34 +// Opcodes: CALLVALUE +// SourceMappings: :::-:0 diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 13018bf18512..289f2f2def35 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(isoltest ../TestCase.cpp ../TestCaseReader.cpp ../libevmasm/EVMAssemblyTest.cpp + ../libevmasm/PlainAssemblyParser.cpp ../libsolidity/util/BytesUtils.cpp ../libsolidity/util/Common.cpp ../libsolidity/util/ContractABIUtils.cpp diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 32309b005507..26efc089020b 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -75,7 +75,7 @@ class TestFilter boost::replace_all(filter, "/", "\\/"); boost::replace_all(filter, "*", ".*"); - m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.asmjson|\\.stack))"}; + m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.asm|\\.asmjson|\\.stack))"}; } bool matches(fs::path const& _path, std::string const& _name) const From 975ee1325833c6784adff85072c55c3ecf9439fc Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 9 Apr 2025 15:30:26 +0200 Subject: [PATCH 067/121] eof: Enable peephole optimizer for EOF. --- libevmasm/Assembly.cpp | 3 +- libevmasm/AssemblyItem.h | 2 +- libevmasm/PeepholeOptimiser.cpp | 12 ++++-- test/Common.cpp | 7 ++++ test/Common.h | 4 ++ test/libevmasm/Optimiser.cpp | 40 +++++++++++++++++++ .../objectCompiler/eof/256_subcontainers.yul | 8 ++-- 7 files changed, 65 insertions(+), 11 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index a0711cd41756..9dd203a0f802 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -843,8 +843,7 @@ std::map const& Assembly::optimiseInternal( } } - // TODO: verify this for EOF. - if (_settings.runPeephole && !m_eofVersion.has_value()) + if (_settings.runPeephole) { for (auto& codeSection: m_codeSections) { diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 8b65d77c91e9..0dfe0749768a 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -244,7 +244,7 @@ class AssemblyItem /// Shortcut that avoids constructing an AssemblyItem just to perform the comparison. bool operator==(Instruction _instr) const { - return type() == Operation && instruction() == _instr; + return hasInstruction() && instruction() == _instr; } bool operator!=(Instruction _instr) const { return !operator==(_instr); } diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index cc22db9fa2fd..267700e457cd 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -563,7 +563,9 @@ struct TruthyAnd: SimplePeepholeOptimizerMethod } }; -/// Removes everything after a JUMP (or similar) until the next JUMPDEST. +/// Removes everything after an non-continuing instruction until the next Tag. +/// Note: JUMPF can return but to the caller's parent call frame. +/// So it won't continue from the next to the JUMPF instruction struct UnreachableCode { static bool apply(OptimiserState& _state) @@ -572,14 +574,18 @@ struct UnreachableCode auto end = _state.items.end(); if (it == end) return false; + if ( it[0] != Instruction::JUMP && - it[0] != Instruction::RJUMP && it[0] != Instruction::RETURN && it[0] != Instruction::STOP && it[0] != Instruction::INVALID && it[0] != Instruction::SELFDESTRUCT && - it[0] != Instruction::REVERT + it[0] != Instruction::REVERT && + it[0] != Instruction::RJUMP && + it[0] != Instruction::JUMPF && + it[0] != Instruction::RETF && + it[0] != Instruction::RETURNCONTRACT ) return false; diff --git a/test/Common.cpp b/test/Common.cpp index d39c6db1ea9e..142afda22e9f 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -313,6 +313,13 @@ boost::unit_test::precondition::predicate_t nonEOF() }; } +boost::unit_test::precondition::predicate_t onEOF() +{ + return [](boost::unit_test::test_unit_id) { + return solidity::test::CommonOptions::get().eofVersion().has_value(); + }; +} + boost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVersion _minEVMVersion) { return [_minEVMVersion](boost::unit_test::test_unit_id) { diff --git a/test/Common.h b/test/Common.h index 27c2081346fc..e331c497a47f 100644 --- a/test/Common.h +++ b/test/Common.h @@ -116,6 +116,10 @@ boost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVers /// @return A predicate (function) that can be passed into @a boost::unit_test::precondition(). boost::unit_test::precondition::predicate_t nonEOF(); +/// Helper that can be used to skip tests when the legacy bytecode is not supported by the test case. +/// @return A predicate (function) that can be passed into @a boost::unit_test::precondition(). +boost::unit_test::precondition::predicate_t onEOF(); + bool loadVMs(CommonOptions const& _options); /** diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index f4b7034de544..4e344c174e00 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1009,6 +1009,46 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code) ); } +BOOST_AUTO_TEST_CASE(clear_unreachable_code_eof, *boost::unit_test::precondition(onEOF())) +{ + for (auto const& blockTerminatingItem: + { + AssemblyItem::relativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem::jumpToFunction(1, 0, 0), + AssemblyItem::functionReturn(), + AssemblyItem::returnContract(0), + } + ) + { + AssemblyItems items{ + blockTerminatingItem, + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 2), + u256(5), + u256(6), + Instruction::SSTORE, + blockTerminatingItem, + u256(5), + u256(6) + }; + AssemblyItems expectation{ + blockTerminatingItem, + AssemblyItem(Tag, 2), + u256(5), + u256(6), + Instruction::SSTORE, + blockTerminatingItem, + }; + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); + } +} + BOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize3) { AssemblyItems items{ diff --git a/test/libyul/objectCompiler/eof/256_subcontainers.yul b/test/libyul/objectCompiler/eof/256_subcontainers.yul index fac0f7b5df29..9306dcbbdeb3 100644 --- a/test/libyul/objectCompiler/eof/256_subcontainers.yul +++ b/test/libyul/objectCompiler/eof/256_subcontainers.yul @@ -2823,8 +2823,6 @@ object "a" { // dup1 // eofcreate{255} // /* "source":12286:12321 */ -// pop -// /* "source":22:12337 */ // stop // stop // @@ -4107,6 +4105,6 @@ object "a" { // /* "source":24612:24619 */ // stop // } -// Bytecode: ef00010100040200010701030100001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001404000000008000045f808080ec00505f808080ec01505f808080ec02505f808080ec03505f808080ec04505f808080ec05505f808080ec06505f808080ec07505f808080ec08505f808080ec09505f808080ec0a505f808080ec0b505f808080ec0c505f808080ec0d505f808080ec0e505f808080ec0f505f808080ec10505f808080ec11505f808080ec12505f808080ec13505f808080ec14505f808080ec15505f808080ec16505f808080ec17505f808080ec18505f808080ec19505f808080ec1a505f808080ec1b505f808080ec1c505f808080ec1d505f808080ec1e505f808080ec1f505f808080ec20505f808080ec21505f808080ec22505f808080ec23505f808080ec24505f808080ec25505f808080ec26505f808080ec27505f808080ec28505f808080ec29505f808080ec2a505f808080ec2b505f808080ec2c505f808080ec2d505f808080ec2e505f808080ec2f505f808080ec30505f808080ec31505f808080ec32505f808080ec33505f808080ec34505f808080ec35505f808080ec36505f808080ec37505f808080ec38505f808080ec39505f808080ec3a505f808080ec3b505f808080ec3c505f808080ec3d505f808080ec3e505f808080ec3f505f808080ec40505f808080ec41505f808080ec42505f808080ec43505f808080ec44505f808080ec45505f808080ec46505f808080ec47505f808080ec48505f808080ec49505f808080ec4a505f808080ec4b505f808080ec4c505f808080ec4d505f808080ec4e505f808080ec4f505f808080ec50505f808080ec51505f808080ec52505f808080ec53505f808080ec54505f808080ec55505f808080ec56505f808080ec57505f808080ec58505f808080ec59505f808080ec5a505f808080ec5b505f808080ec5c505f808080ec5d505f808080ec5e505f808080ec5f505f808080ec60505f808080ec61505f808080ec62505f808080ec63505f808080ec64505f808080ec65505f808080ec66505f808080ec67505f808080ec68505f808080ec69505f808080ec6a505f808080ec6b505f808080ec6c505f808080ec6d505f808080ec6e505f808080ec6f505f808080ec70505f808080ec71505f808080ec72505f808080ec73505f808080ec74505f808080ec75505f808080ec76505f808080ec77505f808080ec78505f808080ec79505f808080ec7a505f808080ec7b505f808080ec7c505f808080ec7d505f808080ec7e505f808080ec7f505f808080ec80505f808080ec81505f808080ec82505f808080ec83505f808080ec84505f808080ec85505f808080ec86505f808080ec87505f808080ec88505f808080ec89505f808080ec8a505f808080ec8b505f808080ec8c505f808080ec8d505f808080ec8e505f808080ec8f505f808080ec90505f808080ec91505f808080ec92505f808080ec93505f808080ec94505f808080ec95505f808080ec96505f808080ec97505f808080ec98505f808080ec99505f808080ec9a505f808080ec9b505f808080ec9c505f808080ec9d505f808080ec9e505f808080ec9f505f808080eca0505f808080eca1505f808080eca2505f808080eca3505f808080eca4505f808080eca5505f808080eca6505f808080eca7505f808080eca8505f808080eca9505f808080ecaa505f808080ecab505f808080ecac505f808080ecad505f808080ecae505f808080ecaf505f808080ecb0505f808080ecb1505f808080ecb2505f808080ecb3505f808080ecb4505f808080ecb5505f808080ecb6505f808080ecb7505f808080ecb8505f808080ecb9505f808080ecba505f808080ecbb505f808080ecbc505f808080ecbd505f808080ecbe505f808080ecbf505f808080ecc0505f808080ecc1505f808080ecc2505f808080ecc3505f808080ecc4505f808080ecc5505f808080ecc6505f808080ecc7505f808080ecc8505f808080ecc9505f808080ecca505f808080eccb505f808080eccc505f808080eccd505f808080ecce505f808080eccf505f808080ecd0505f808080ecd1505f808080ecd2505f808080ecd3505f808080ecd4505f808080ecd5505f808080ecd6505f808080ecd7505f808080ecd8505f808080ecd9505f808080ecda505f808080ecdb505f808080ecdc505f808080ecdd505f808080ecde505f808080ecdf505f808080ece0505f808080ece1505f808080ece2505f808080ece3505f808080ece4505f808080ece5505f808080ece6505f808080ece7505f808080ece8505f808080ece9505f808080ecea505f808080eceb505f808080ecec505f808080eced505f808080ecee505f808080ecef505f808080ecf0505f808080ecf1505f808080ecf2505f808080ecf3505f808080ecf4505f808080ecf5505f808080ecf6505f808080ecf7505f808080ecf8505f808080ecf9505f808080ecfa505f808080ecfb505f808080ecfc505f808080ecfd505f808080ecfe505f808080ecff5000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000 -// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD SMOD ADD SUB ADD STOP STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ DIV STOP STOP STOP STOP DUP1 STOP DIV PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x10 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x11 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x12 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x13 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x14 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x15 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x16 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x17 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x18 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x19 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x20 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x21 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x22 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x23 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x24 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x25 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x26 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x27 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x28 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x29 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x30 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x31 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x32 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x33 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x34 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x35 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x36 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x37 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x38 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x39 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x40 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x41 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x42 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x43 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x44 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x45 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x46 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x47 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x48 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x49 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x50 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x51 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x52 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x53 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x54 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x55 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x56 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x57 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x58 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x59 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x60 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x61 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x62 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x63 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x64 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x65 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x66 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x67 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x68 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x69 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x70 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x71 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x72 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x73 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x74 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x75 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x76 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x77 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x78 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x79 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x80 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x81 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x82 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x83 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x84 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x85 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x86 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x87 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x88 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x89 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x90 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x91 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x92 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x93 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x94 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x95 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x96 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x97 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x98 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x99 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xED POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFF POP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP -// SourceMappings: 78:1:0:-:0;50:30;;;;46:35;126:1;98:30;;;;94:35;174:1;146:30;;;;142:35;222:1;194:30;;;;190:35;270:1;242:30;;;;238:35;318:1;290:30;;;;286:35;366:1;338:30;;;;334:35;414:1;386:30;;;;382:35;462:1;434:30;;;;430:35;510:1;482:30;;;;478:35;558:1;530:30;;;;526:35;606:1;578:30;;;;574:35;654:1;626:30;;;;622:35;702:1;674:30;;;;670:35;750:1;722:30;;;;718:35;798:1;770:30;;;;766:35;846:1;818:30;;;;814:35;894:1;866:30;;;;862:35;942:1;914:30;;;;910:35;990:1;962:30;;;;958:35;1038:1;1010:30;;;;1006:35;1086:1;1058:30;;;;1054:35;1134:1;1106:30;;;;1102:35;1182:1;1154:30;;;;1150:35;1230:1;1202:30;;;;1198:35;1278:1;1250:30;;;;1246:35;1326:1;1298:30;;;;1294:35;1374:1;1346:30;;;;1342:35;1422:1;1394:30;;;;1390:35;1470:1;1442:30;;;;1438:35;1518:1;1490:30;;;;1486:35;1566:1;1538:30;;;;1534:35;1614:1;1586:30;;;;1582:35;1662:1;1634:30;;;;1630:35;1710:1;1682:30;;;;1678:35;1758:1;1730:30;;;;1726:35;1806:1;1778:30;;;;1774:35;1854:1;1826:30;;;;1822:35;1902:1;1874:30;;;;1870:35;1950:1;1922:30;;;;1918:35;1998:1;1970:30;;;;1966:35;2046:1;2018:30;;;;2014:35;2094:1;2066:30;;;;2062:35;2142:1;2114:30;;;;2110:35;2190:1;2162:30;;;;2158:35;2238:1;2210:30;;;;2206:35;2286:1;2258:30;;;;2254:35;2334:1;2306:30;;;;2302:35;2382:1;2354:30;;;;2350:35;2430:1;2402:30;;;;2398:35;2478:1;2450:30;;;;2446:35;2526:1;2498:30;;;;2494:35;2574:1;2546:30;;;;2542:35;2622:1;2594:30;;;;2590:35;2670:1;2642:30;;;;2638:35;2718:1;2690:30;;;;2686:35;2766:1;2738:30;;;;2734:35;2814:1;2786:30;;;;2782:35;2862:1;2834:30;;;;2830:35;2910:1;2882:30;;;;2878:35;2958:1;2930:30;;;;2926:35;3006:1;2978:30;;;;2974:35;3054:1;3026:30;;;;3022:35;3102:1;3074:30;;;;3070:35;3150:1;3122:30;;;;3118:35;3198:1;3170:30;;;;3166:35;3246:1;3218:30;;;;3214:35;3294:1;3266:30;;;;3262:35;3342:1;3314:30;;;;3310:35;3390:1;3362:30;;;;3358:35;3438:1;3410:30;;;;3406:35;3486:1;3458:30;;;;3454:35;3534:1;3506:30;;;;3502:35;3582:1;3554:30;;;;3550:35;3630:1;3602:30;;;;3598:35;3678:1;3650:30;;;;3646:35;3726:1;3698:30;;;;3694:35;3774:1;3746:30;;;;3742:35;3822:1;3794:30;;;;3790:35;3870:1;3842:30;;;;3838:35;3918:1;3890:30;;;;3886:35;3966:1;3938:30;;;;3934:35;4014:1;3986:30;;;;3982:35;4062:1;4034:30;;;;4030:35;4110:1;4082:30;;;;4078:35;4158:1;4130:30;;;;4126:35;4206:1;4178:30;;;;4174:35;4254:1;4226:30;;;;4222:35;4302:1;4274:30;;;;4270:35;4350:1;4322:30;;;;4318:35;4398:1;4370:30;;;;4366:35;4446:1;4418:30;;;;4414:35;4494:1;4466:30;;;;4462:35;4542:1;4514:30;;;;4510:35;4590:1;4562:30;;;;4558:35;4638:1;4610:30;;;;4606:35;4686:1;4658:30;;;;4654:35;4734:1;4706:30;;;;4702:35;4782:1;4754:30;;;;4750:35;4830:1;4802:30;;;;4798:35;4878:1;4850:30;;;;4846:35;4926:1;4898:30;;;;4894:35;4974:1;4946:30;;;;4942:35;5022:1;4994:30;;;;4990:35;5070:1;5042:30;;;;5038:35;5118:1;5090:30;;;;5086:35;5166:1;5138:30;;;;5134:35;5214:1;5186:30;;;;5182:35;5262:1;5234:30;;;;5230:35;5310:1;5282:30;;;;5278:35;5358:1;5330:30;;;;5326:35;5406:1;5378:30;;;;5374:35;5454:1;5426:30;;;;5422:35;5502:1;5474:30;;;;5470:35;5550:1;5522:30;;;;5518:35;5598:1;5570:30;;;;5566:35;5646:1;5618:30;;;;5614:35;5694:1;5666:30;;;;5662:35;5742:1;5714:30;;;;5710:35;5790:1;5762:30;;;;5758:35;5838:1;5810:30;;;;5806:35;5886:1;5858:30;;;;5854:35;5934:1;5906:30;;;;5902:35;5982:1;5954:30;;;;5950:35;6030:1;6002:30;;;;5998:35;6078:1;6050:30;;;;6046:35;6126:1;6098:30;;;;6094:35;6174:1;6146:30;;;;6142:35;6222:1;6194:30;;;;6190:35;6270:1;6242:30;;;;6238:35;6318:1;6290:30;;;;6286:35;6366:1;6338:30;;;;6334:35;6414:1;6386:30;;;;6382:35;6462:1;6434:30;;;;6430:35;6510:1;6482:30;;;;6478:35;6558:1;6530:30;;;;6526:35;6606:1;6578:30;;;;6574:35;6654:1;6626:30;;;;6622:35;6702:1;6674:30;;;;6670:35;6750:1;6722:30;;;;6718:35;6798:1;6770:30;;;;6766:35;6846:1;6818:30;;;;6814:35;6894:1;6866:30;;;;6862:35;6942:1;6914:30;;;;6910:35;6990:1;6962:30;;;;6958:35;7038:1;7010:30;;;;7006:35;7086:1;7058:30;;;;7054:35;7134:1;7106:30;;;;7102:35;7182:1;7154:30;;;;7150:35;7230:1;7202:30;;;;7198:35;7278:1;7250:30;;;;7246:35;7326:1;7298:30;;;;7294:35;7374:1;7346:30;;;;7342:35;7422:1;7394:30;;;;7390:35;7470:1;7442:30;;;;7438:35;7518:1;7490:30;;;;7486:35;7566:1;7538:30;;;;7534:35;7614:1;7586:30;;;;7582:35;7662:1;7634:30;;;;7630:35;7710:1;7682:30;;;;7678:35;7758:1;7730:30;;;;7726:35;7806:1;7778:30;;;;7774:35;7854:1;7826:30;;;;7822:35;7902:1;7874:30;;;;7870:35;7950:1;7922:30;;;;7918:35;7998:1;7970:30;;;;7966:35;8046:1;8018:30;;;;8014:35;8094:1;8066:30;;;;8062:35;8142:1;8114:30;;;;8110:35;8190:1;8162:30;;;;8158:35;8238:1;8210:30;;;;8206:35;8286:1;8258:30;;;;8254:35;8334:1;8306:30;;;;8302:35;8382:1;8354:30;;;;8350:35;8430:1;8402:30;;;;8398:35;8478:1;8450:30;;;;8446:35;8526:1;8498:30;;;;8494:35;8574:1;8546:30;;;;8542:35;8622:1;8594:30;;;;8590:35;8670:1;8642:30;;;;8638:35;8718:1;8690:30;;;;8686:35;8766:1;8738:30;;;;8734:35;8814:1;8786:30;;;;8782:35;8862:1;8834:30;;;;8830:35;8910:1;8882:30;;;;8878:35;8958:1;8930:30;;;;8926:35;9006:1;8978:30;;;;8974:35;9054:1;9026:30;;;;9022:35;9102:1;9074:30;;;;9070:35;9150:1;9122:30;;;;9118:35;9198:1;9170:30;;;;9166:35;9246:1;9218:30;;;;9214:35;9294:1;9266:30;;;;9262:35;9342:1;9314:30;;;;9310:35;9390:1;9362:30;;;;9358:35;9438:1;9410:30;;;;9406:35;9486:1;9458:30;;;;9454:35;9534:1;9506:30;;;;9502:35;9582:1;9554:30;;;;9550:35;9630:1;9602:30;;;;9598:35;9678:1;9650:30;;;;9646:35;9726:1;9698:30;;;;9694:35;9774:1;9746:30;;;;9742:35;9822:1;9794:30;;;;9790:35;9870:1;9842:30;;;;9838:35;9918:1;9890:30;;;;9886:35;9966:1;9938:30;;;;9934:35;10014:1;9986:30;;;;9982:35;10062:1;10034:30;;;;10030:35;10110:1;10082:30;;;;10078:35;10158:1;10130:30;;;;10126:35;10206:1;10178:30;;;;10174:35;10254:1;10226:30;;;;10222:35;10302:1;10274:30;;;;10270:35;10350:1;10322:30;;;;10318:35;10398:1;10370:30;;;;10366:35;10446:1;10418:30;;;;10414:35;10494:1;10466:30;;;;10462:35;10542:1;10514:30;;;;10510:35;10590:1;10562:30;;;;10558:35;10638:1;10610:30;;;;10606:35;10686:1;10658:30;;;;10654:35;10734:1;10706:30;;;;10702:35;10782:1;10754:30;;;;10750:35;10830:1;10802:30;;;;10798:35;10878:1;10850:30;;;;10846:35;10926:1;10898:30;;;;10894:35;10974:1;10946:30;;;;10942:35;11022:1;10994:30;;;;10990:35;11070:1;11042:30;;;;11038:35;11118:1;11090:30;;;;11086:35;11166:1;11138:30;;;;11134:35;11214:1;11186:30;;;;11182:35;11262:1;11234:30;;;;11230:35;11310:1;11282:30;;;;11278:35;11358:1;11330:30;;;;11326:35;11406:1;11378:30;;;;11374:35;11454:1;11426:30;;;;11422:35;11502:1;11474:30;;;;11470:35;11550:1;11522:30;;;;11518:35;11598:1;11570:30;;;;11566:35;11646:1;11618:30;;;;11614:35;11694:1;11666:30;;;;11662:35;11742:1;11714:30;;;;11710:35;11790:1;11762:30;;;;11758:35;11838:1;11810:30;;;;11806:35;11886:1;11858:30;;;;11854:35;11934:1;11906:30;;;;11902:35;11982:1;11954:30;;;;11950:35;12030:1;12002:30;;;;11998:35;12078:1;12050:30;;;;12046:35;12126:1;12098:30;;;;12094:35;12174:1;12146:30;;;;12142:35;12222:1;12194:30;;;;12190:35;12270:1;12242:30;;;;12238:35;12318:1;12290:30;;;;12286:35;22:12315 +// Bytecode: ef00010100040200010700030100001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001404000000008000045f808080ec00505f808080ec01505f808080ec02505f808080ec03505f808080ec04505f808080ec05505f808080ec06505f808080ec07505f808080ec08505f808080ec09505f808080ec0a505f808080ec0b505f808080ec0c505f808080ec0d505f808080ec0e505f808080ec0f505f808080ec10505f808080ec11505f808080ec12505f808080ec13505f808080ec14505f808080ec15505f808080ec16505f808080ec17505f808080ec18505f808080ec19505f808080ec1a505f808080ec1b505f808080ec1c505f808080ec1d505f808080ec1e505f808080ec1f505f808080ec20505f808080ec21505f808080ec22505f808080ec23505f808080ec24505f808080ec25505f808080ec26505f808080ec27505f808080ec28505f808080ec29505f808080ec2a505f808080ec2b505f808080ec2c505f808080ec2d505f808080ec2e505f808080ec2f505f808080ec30505f808080ec31505f808080ec32505f808080ec33505f808080ec34505f808080ec35505f808080ec36505f808080ec37505f808080ec38505f808080ec39505f808080ec3a505f808080ec3b505f808080ec3c505f808080ec3d505f808080ec3e505f808080ec3f505f808080ec40505f808080ec41505f808080ec42505f808080ec43505f808080ec44505f808080ec45505f808080ec46505f808080ec47505f808080ec48505f808080ec49505f808080ec4a505f808080ec4b505f808080ec4c505f808080ec4d505f808080ec4e505f808080ec4f505f808080ec50505f808080ec51505f808080ec52505f808080ec53505f808080ec54505f808080ec55505f808080ec56505f808080ec57505f808080ec58505f808080ec59505f808080ec5a505f808080ec5b505f808080ec5c505f808080ec5d505f808080ec5e505f808080ec5f505f808080ec60505f808080ec61505f808080ec62505f808080ec63505f808080ec64505f808080ec65505f808080ec66505f808080ec67505f808080ec68505f808080ec69505f808080ec6a505f808080ec6b505f808080ec6c505f808080ec6d505f808080ec6e505f808080ec6f505f808080ec70505f808080ec71505f808080ec72505f808080ec73505f808080ec74505f808080ec75505f808080ec76505f808080ec77505f808080ec78505f808080ec79505f808080ec7a505f808080ec7b505f808080ec7c505f808080ec7d505f808080ec7e505f808080ec7f505f808080ec80505f808080ec81505f808080ec82505f808080ec83505f808080ec84505f808080ec85505f808080ec86505f808080ec87505f808080ec88505f808080ec89505f808080ec8a505f808080ec8b505f808080ec8c505f808080ec8d505f808080ec8e505f808080ec8f505f808080ec90505f808080ec91505f808080ec92505f808080ec93505f808080ec94505f808080ec95505f808080ec96505f808080ec97505f808080ec98505f808080ec99505f808080ec9a505f808080ec9b505f808080ec9c505f808080ec9d505f808080ec9e505f808080ec9f505f808080eca0505f808080eca1505f808080eca2505f808080eca3505f808080eca4505f808080eca5505f808080eca6505f808080eca7505f808080eca8505f808080eca9505f808080ecaa505f808080ecab505f808080ecac505f808080ecad505f808080ecae505f808080ecaf505f808080ecb0505f808080ecb1505f808080ecb2505f808080ecb3505f808080ecb4505f808080ecb5505f808080ecb6505f808080ecb7505f808080ecb8505f808080ecb9505f808080ecba505f808080ecbb505f808080ecbc505f808080ecbd505f808080ecbe505f808080ecbf505f808080ecc0505f808080ecc1505f808080ecc2505f808080ecc3505f808080ecc4505f808080ecc5505f808080ecc6505f808080ecc7505f808080ecc8505f808080ecc9505f808080ecca505f808080eccb505f808080eccc505f808080eccd505f808080ecce505f808080eccf505f808080ecd0505f808080ecd1505f808080ecd2505f808080ecd3505f808080ecd4505f808080ecd5505f808080ecd6505f808080ecd7505f808080ecd8505f808080ecd9505f808080ecda505f808080ecdb505f808080ecdc505f808080ecdd505f808080ecde505f808080ecdf505f808080ece0505f808080ece1505f808080ece2505f808080ece3505f808080ece4505f808080ece5505f808080ece6505f808080ece7505f808080ece8505f808080ece9505f808080ecea505f808080eceb505f808080ecec505f808080eced505f808080ecee505f808080ecef505f808080ecf0505f808080ecf1505f808080ecf2505f808080ecf3505f808080ecf4505f808080ecf5505f808080ecf6505f808080ecf7505f808080ecf8505f808080ecf9505f808080ecfa505f808080ecfb505f808080ecfc505f808080ecfd505f808080ecfe505f808080ecff00ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD SMOD STOP SUB ADD STOP STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ DIV STOP STOP STOP STOP DUP1 STOP DIV PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x10 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x11 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x12 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x13 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x14 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x15 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x16 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x17 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x18 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x19 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x20 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x21 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x22 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x23 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x24 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x25 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x26 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x27 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x28 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x29 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x30 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x31 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x32 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x33 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x34 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x35 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x36 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x37 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x38 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x39 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x40 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x41 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x42 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x43 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x44 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x45 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x46 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x47 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x48 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x49 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x50 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x51 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x52 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x53 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x54 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x55 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x56 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x57 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x58 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x59 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x60 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x61 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x62 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x63 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x64 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x65 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x66 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x67 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x68 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x69 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x70 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x71 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x72 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x73 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x74 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x75 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x76 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x77 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x78 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x79 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x80 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x81 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x82 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x83 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x84 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x85 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x86 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x87 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x88 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x89 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x90 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x91 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x92 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x93 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x94 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x95 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x96 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x97 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x98 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x99 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xED POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFF STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP +// SourceMappings: 78:1:0:-:0;50:30;;;;46:35;126:1;98:30;;;;94:35;174:1;146:30;;;;142:35;222:1;194:30;;;;190:35;270:1;242:30;;;;238:35;318:1;290:30;;;;286:35;366:1;338:30;;;;334:35;414:1;386:30;;;;382:35;462:1;434:30;;;;430:35;510:1;482:30;;;;478:35;558:1;530:30;;;;526:35;606:1;578:30;;;;574:35;654:1;626:30;;;;622:35;702:1;674:30;;;;670:35;750:1;722:30;;;;718:35;798:1;770:30;;;;766:35;846:1;818:30;;;;814:35;894:1;866:30;;;;862:35;942:1;914:30;;;;910:35;990:1;962:30;;;;958:35;1038:1;1010:30;;;;1006:35;1086:1;1058:30;;;;1054:35;1134:1;1106:30;;;;1102:35;1182:1;1154:30;;;;1150:35;1230:1;1202:30;;;;1198:35;1278:1;1250:30;;;;1246:35;1326:1;1298:30;;;;1294:35;1374:1;1346:30;;;;1342:35;1422:1;1394:30;;;;1390:35;1470:1;1442:30;;;;1438:35;1518:1;1490:30;;;;1486:35;1566:1;1538:30;;;;1534:35;1614:1;1586:30;;;;1582:35;1662:1;1634:30;;;;1630:35;1710:1;1682:30;;;;1678:35;1758:1;1730:30;;;;1726:35;1806:1;1778:30;;;;1774:35;1854:1;1826:30;;;;1822:35;1902:1;1874:30;;;;1870:35;1950:1;1922:30;;;;1918:35;1998:1;1970:30;;;;1966:35;2046:1;2018:30;;;;2014:35;2094:1;2066:30;;;;2062:35;2142:1;2114:30;;;;2110:35;2190:1;2162:30;;;;2158:35;2238:1;2210:30;;;;2206:35;2286:1;2258:30;;;;2254:35;2334:1;2306:30;;;;2302:35;2382:1;2354:30;;;;2350:35;2430:1;2402:30;;;;2398:35;2478:1;2450:30;;;;2446:35;2526:1;2498:30;;;;2494:35;2574:1;2546:30;;;;2542:35;2622:1;2594:30;;;;2590:35;2670:1;2642:30;;;;2638:35;2718:1;2690:30;;;;2686:35;2766:1;2738:30;;;;2734:35;2814:1;2786:30;;;;2782:35;2862:1;2834:30;;;;2830:35;2910:1;2882:30;;;;2878:35;2958:1;2930:30;;;;2926:35;3006:1;2978:30;;;;2974:35;3054:1;3026:30;;;;3022:35;3102:1;3074:30;;;;3070:35;3150:1;3122:30;;;;3118:35;3198:1;3170:30;;;;3166:35;3246:1;3218:30;;;;3214:35;3294:1;3266:30;;;;3262:35;3342:1;3314:30;;;;3310:35;3390:1;3362:30;;;;3358:35;3438:1;3410:30;;;;3406:35;3486:1;3458:30;;;;3454:35;3534:1;3506:30;;;;3502:35;3582:1;3554:30;;;;3550:35;3630:1;3602:30;;;;3598:35;3678:1;3650:30;;;;3646:35;3726:1;3698:30;;;;3694:35;3774:1;3746:30;;;;3742:35;3822:1;3794:30;;;;3790:35;3870:1;3842:30;;;;3838:35;3918:1;3890:30;;;;3886:35;3966:1;3938:30;;;;3934:35;4014:1;3986:30;;;;3982:35;4062:1;4034:30;;;;4030:35;4110:1;4082:30;;;;4078:35;4158:1;4130:30;;;;4126:35;4206:1;4178:30;;;;4174:35;4254:1;4226:30;;;;4222:35;4302:1;4274:30;;;;4270:35;4350:1;4322:30;;;;4318:35;4398:1;4370:30;;;;4366:35;4446:1;4418:30;;;;4414:35;4494:1;4466:30;;;;4462:35;4542:1;4514:30;;;;4510:35;4590:1;4562:30;;;;4558:35;4638:1;4610:30;;;;4606:35;4686:1;4658:30;;;;4654:35;4734:1;4706:30;;;;4702:35;4782:1;4754:30;;;;4750:35;4830:1;4802:30;;;;4798:35;4878:1;4850:30;;;;4846:35;4926:1;4898:30;;;;4894:35;4974:1;4946:30;;;;4942:35;5022:1;4994:30;;;;4990:35;5070:1;5042:30;;;;5038:35;5118:1;5090:30;;;;5086:35;5166:1;5138:30;;;;5134:35;5214:1;5186:30;;;;5182:35;5262:1;5234:30;;;;5230:35;5310:1;5282:30;;;;5278:35;5358:1;5330:30;;;;5326:35;5406:1;5378:30;;;;5374:35;5454:1;5426:30;;;;5422:35;5502:1;5474:30;;;;5470:35;5550:1;5522:30;;;;5518:35;5598:1;5570:30;;;;5566:35;5646:1;5618:30;;;;5614:35;5694:1;5666:30;;;;5662:35;5742:1;5714:30;;;;5710:35;5790:1;5762:30;;;;5758:35;5838:1;5810:30;;;;5806:35;5886:1;5858:30;;;;5854:35;5934:1;5906:30;;;;5902:35;5982:1;5954:30;;;;5950:35;6030:1;6002:30;;;;5998:35;6078:1;6050:30;;;;6046:35;6126:1;6098:30;;;;6094:35;6174:1;6146:30;;;;6142:35;6222:1;6194:30;;;;6190:35;6270:1;6242:30;;;;6238:35;6318:1;6290:30;;;;6286:35;6366:1;6338:30;;;;6334:35;6414:1;6386:30;;;;6382:35;6462:1;6434:30;;;;6430:35;6510:1;6482:30;;;;6478:35;6558:1;6530:30;;;;6526:35;6606:1;6578:30;;;;6574:35;6654:1;6626:30;;;;6622:35;6702:1;6674:30;;;;6670:35;6750:1;6722:30;;;;6718:35;6798:1;6770:30;;;;6766:35;6846:1;6818:30;;;;6814:35;6894:1;6866:30;;;;6862:35;6942:1;6914:30;;;;6910:35;6990:1;6962:30;;;;6958:35;7038:1;7010:30;;;;7006:35;7086:1;7058:30;;;;7054:35;7134:1;7106:30;;;;7102:35;7182:1;7154:30;;;;7150:35;7230:1;7202:30;;;;7198:35;7278:1;7250:30;;;;7246:35;7326:1;7298:30;;;;7294:35;7374:1;7346:30;;;;7342:35;7422:1;7394:30;;;;7390:35;7470:1;7442:30;;;;7438:35;7518:1;7490:30;;;;7486:35;7566:1;7538:30;;;;7534:35;7614:1;7586:30;;;;7582:35;7662:1;7634:30;;;;7630:35;7710:1;7682:30;;;;7678:35;7758:1;7730:30;;;;7726:35;7806:1;7778:30;;;;7774:35;7854:1;7826:30;;;;7822:35;7902:1;7874:30;;;;7870:35;7950:1;7922:30;;;;7918:35;7998:1;7970:30;;;;7966:35;8046:1;8018:30;;;;8014:35;8094:1;8066:30;;;;8062:35;8142:1;8114:30;;;;8110:35;8190:1;8162:30;;;;8158:35;8238:1;8210:30;;;;8206:35;8286:1;8258:30;;;;8254:35;8334:1;8306:30;;;;8302:35;8382:1;8354:30;;;;8350:35;8430:1;8402:30;;;;8398:35;8478:1;8450:30;;;;8446:35;8526:1;8498:30;;;;8494:35;8574:1;8546:30;;;;8542:35;8622:1;8594:30;;;;8590:35;8670:1;8642:30;;;;8638:35;8718:1;8690:30;;;;8686:35;8766:1;8738:30;;;;8734:35;8814:1;8786:30;;;;8782:35;8862:1;8834:30;;;;8830:35;8910:1;8882:30;;;;8878:35;8958:1;8930:30;;;;8926:35;9006:1;8978:30;;;;8974:35;9054:1;9026:30;;;;9022:35;9102:1;9074:30;;;;9070:35;9150:1;9122:30;;;;9118:35;9198:1;9170:30;;;;9166:35;9246:1;9218:30;;;;9214:35;9294:1;9266:30;;;;9262:35;9342:1;9314:30;;;;9310:35;9390:1;9362:30;;;;9358:35;9438:1;9410:30;;;;9406:35;9486:1;9458:30;;;;9454:35;9534:1;9506:30;;;;9502:35;9582:1;9554:30;;;;9550:35;9630:1;9602:30;;;;9598:35;9678:1;9650:30;;;;9646:35;9726:1;9698:30;;;;9694:35;9774:1;9746:30;;;;9742:35;9822:1;9794:30;;;;9790:35;9870:1;9842:30;;;;9838:35;9918:1;9890:30;;;;9886:35;9966:1;9938:30;;;;9934:35;10014:1;9986:30;;;;9982:35;10062:1;10034:30;;;;10030:35;10110:1;10082:30;;;;10078:35;10158:1;10130:30;;;;10126:35;10206:1;10178:30;;;;10174:35;10254:1;10226:30;;;;10222:35;10302:1;10274:30;;;;10270:35;10350:1;10322:30;;;;10318:35;10398:1;10370:30;;;;10366:35;10446:1;10418:30;;;;10414:35;10494:1;10466:30;;;;10462:35;10542:1;10514:30;;;;10510:35;10590:1;10562:30;;;;10558:35;10638:1;10610:30;;;;10606:35;10686:1;10658:30;;;;10654:35;10734:1;10706:30;;;;10702:35;10782:1;10754:30;;;;10750:35;10830:1;10802:30;;;;10798:35;10878:1;10850:30;;;;10846:35;10926:1;10898:30;;;;10894:35;10974:1;10946:30;;;;10942:35;11022:1;10994:30;;;;10990:35;11070:1;11042:30;;;;11038:35;11118:1;11090:30;;;;11086:35;11166:1;11138:30;;;;11134:35;11214:1;11186:30;;;;11182:35;11262:1;11234:30;;;;11230:35;11310:1;11282:30;;;;11278:35;11358:1;11330:30;;;;11326:35;11406:1;11378:30;;;;11374:35;11454:1;11426:30;;;;11422:35;11502:1;11474:30;;;;11470:35;11550:1;11522:30;;;;11518:35;11598:1;11570:30;;;;11566:35;11646:1;11618:30;;;;11614:35;11694:1;11666:30;;;;11662:35;11742:1;11714:30;;;;11710:35;11790:1;11762:30;;;;11758:35;11838:1;11810:30;;;;11806:35;11886:1;11858:30;;;;11854:35;11934:1;11906:30;;;;11902:35;11982:1;11954:30;;;;11950:35;12030:1;12002:30;;;;11998:35;12078:1;12050:30;;;;12046:35;12126:1;12098:30;;;;12094:35;12174:1;12146:30;;;;12142:35;12222:1;12194:30;;;;12190:35;12270:1;12242:30;;;;12238:35;12318:1;12290:30;;;;12286:35 From 03fde2ae36f3a306d14788c175c649d508d6ed42 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 23 Apr 2025 12:27:48 +0200 Subject: [PATCH 068/121] eof: Add peephole optimiser tests for EOF specific optimisations --- test/libevmasm/Optimiser.cpp | 136 +++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 4e344c174e00..b53205e959e5 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1049,6 +1049,142 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code_eof, *boost::unit_test::precondition } } +BOOST_AUTO_TEST_CASE(is_zero_is_zero_rjumpi, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + u256(1), + Instruction::ISZERO, + Instruction::ISZERO, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + AssemblyItems expectation{ + u256(1), + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(equal_is_zero_rjumpi, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + u256(1), + u256(2), + Instruction::EQ, + Instruction::ISZERO, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + AssemblyItems expectation{ + u256(1), + u256(2), + Instruction::SUB, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(double_rjump, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + u256(1), + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem::relativeJumpTo(AssemblyItem(Tag, 2)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 2), + }; + + AssemblyItems expectation{ + u256(1), + Instruction::ISZERO, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 2)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 2), + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(rjump_to_next, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + AssemblyItem::relativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + AssemblyItems expectation{ + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(rjumpi_to_next, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + AssemblyItems expectation{ + Instruction::POP, + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + BOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize3) { AssemblyItems items{ From 649c8ee32826476600f67e2f879859563c92dc00 Mon Sep 17 00:00:00 2001 From: Maximilian Hubert <64627729+gap-editor@users.noreply.github.com> Date: Sat, 26 Apr 2025 17:40:13 +0200 Subject: [PATCH 069/121] Update SMTPortfolio.cpp --- libsmtutil/SMTPortfolio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsmtutil/SMTPortfolio.cpp b/libsmtutil/SMTPortfolio.cpp index 94c92f390a53..e6f6e9913a59 100644 --- a/libsmtutil/SMTPortfolio.cpp +++ b/libsmtutil/SMTPortfolio.cpp @@ -78,7 +78,7 @@ void SMTPortfolio::addAssertion(Expression const& _expr) * Ideally all solvers answer the query and agree on what the answer is * (all say SAT or all say UNSAT). * - * The actual logic as as follows: + * The actual logic as follows: * 1) If at least one solver answers the query, all the non-answer results are ignored. * Here SAT/UNSAT is preferred over UNKNOWN since it's an actual answer, and over ERROR * because one buggy solver/integration shouldn't break the portfolio. From 76e80168f10e560f159309edf3448f48fb80dc0e Mon Sep 17 00:00:00 2001 From: Maximilian Hubert <64627729+gap-editor@users.noreply.github.com> Date: Mon, 28 Apr 2025 11:27:07 +0200 Subject: [PATCH 070/121] Update SMTPortfolio.cpp --- libsmtutil/SMTPortfolio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsmtutil/SMTPortfolio.cpp b/libsmtutil/SMTPortfolio.cpp index e6f6e9913a59..fb82f3c69361 100644 --- a/libsmtutil/SMTPortfolio.cpp +++ b/libsmtutil/SMTPortfolio.cpp @@ -78,7 +78,7 @@ void SMTPortfolio::addAssertion(Expression const& _expr) * Ideally all solvers answer the query and agree on what the answer is * (all say SAT or all say UNSAT). * - * The actual logic as follows: + * The actual logic is as follows: * 1) If at least one solver answers the query, all the non-answer results are ignored. * Here SAT/UNSAT is preferred over UNKNOWN since it's an actual answer, and over ERROR * because one buggy solver/integration shouldn't break the portfolio. From 09fc1d4a21504a9cfd0c645a7754015c18933eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Apr 2025 06:10:31 +0200 Subject: [PATCH 071/121] PlainAssemblyParser: Store the stream globally in the class --- test/libevmasm/PlainAssemblyParser.cpp | 37 +++++++++++++++++++------- test/libevmasm/PlainAssemblyParser.h | 14 +++++----- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp index 0fb9d62c8c10..4d09043b1623 100644 --- a/test/libevmasm/PlainAssemblyParser.cpp +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -28,8 +28,6 @@ #include -#include - using namespace std::string_literals; using namespace solidity; using namespace solidity::test; @@ -39,15 +37,21 @@ using namespace solidity::langutil; Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _source) { + m_sourceStream = std::istringstream(_source); m_sourceName = std::move(_sourceName); Json codeJSON = Json::array(); - std::istringstream sourceStream(_source); - while (getline(sourceStream, m_line)) + m_lineNumber = 0; + + if (!m_line.has_value()) + advanceLine(); + + while (m_line.has_value()) { - advanceLine(m_line); if (m_lineTokens.empty()) + { + advanceLine(); continue; - + } if (c_instructions.contains(currentToken().value)) { expectNoMoreArguments(); @@ -84,6 +88,8 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou } else BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Unknown instruction."))); + + advanceLine(); } return {{".code", codeJSON}}; } @@ -125,12 +131,20 @@ void PlainAssemblyParser::expectNoMoreArguments() BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Too many arguments."))); } -void PlainAssemblyParser::advanceLine(std::string_view _line) +bool PlainAssemblyParser::advanceLine() { + std::string line; + if (!getline(m_sourceStream, line)) + { + m_line = std::nullopt; + return false; + } + ++m_lineNumber; - m_line = _line; - m_lineTokens = tokenizeLine(m_line); + m_line = std::move(line); + m_lineTokens = tokenizeLine(*m_line); m_tokenIndex = 0; + return true; } std::vector PlainAssemblyParser::tokenizeLine(std::string_view _line) @@ -162,6 +176,9 @@ std::vector PlainAssemblyParser::tokenizeLine(std::s std::string PlainAssemblyParser::formatError(std::string_view _message) const { + soltestAssert(m_line.has_value()); + soltestAssert(!m_lineTokens.empty()); + std::string lineNumberString = std::to_string(m_lineNumber); std::string padding(lineNumberString.size(), ' '); std::string underline = std::string(currentToken().position, ' ') + std::string(currentToken().value.size(), '^'); @@ -174,7 +191,7 @@ std::string PlainAssemblyParser::formatError(std::string_view _message) const _message, padding, m_sourceName, padding, - m_lineNumber, m_line, + m_lineNumber, *m_line, padding, underline ); } diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h index 0154af5f7f19..95cc3ee8f84e 100644 --- a/test/libevmasm/PlainAssemblyParser.h +++ b/test/libevmasm/PlainAssemblyParser.h @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -63,17 +64,18 @@ class PlainAssemblyParser bool advanceToken(); std::string_view expectArgument(); void expectNoMoreArguments(); - void advanceLine(std::string_view _line); + bool advanceLine(); static std::vector tokenizeLine(std::string_view _line); std::string formatError(std::string_view _message) const; private: - std::string m_sourceName; ///< Name of the file the source comes from. - size_t m_lineNumber = 0; ///< The number of the current line within the source, 1-based. - std::string m_line; ///< The current line, unparsed. - std::vector m_lineTokens; ///< Decomposition of the current line into tokens (does not include comments). - size_t m_tokenIndex = 0; ///< Points at a token within m_lineTokens. + std::istringstream m_sourceStream; ///< The source code being parsed. + std::string m_sourceName; ///< Name of the file the source comes from. + size_t m_lineNumber = 0; ///< The number of the current line within the source, 1-based. + std::optional m_line; ///< The current line, unparsed. + std::vector m_lineTokens; ///< Decomposition of the current line into tokens (does not include comments). + size_t m_tokenIndex = 0; ///< Points at a token within m_lineTokens. }; } From 73af6528bdd323d8c62fea2788525ad191a8ee3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Apr 2025 06:17:46 +0200 Subject: [PATCH 072/121] PlainAssemblyParser: Syntax for subassemblies --- test/libevmasm/PlainAssemblyParser.cpp | 56 +++++- test/libevmasm/PlainAssemblyParser.h | 11 ++ .../isoltestTesting/empty.asm | 10 + .../isoltestTesting/subassemblies.asm | 69 +++++++ .../isoltestTesting/subassemblies_empty.asm | 34 ++++ .../isoltestTesting/subassemblies_nested.asm | 171 ++++++++++++++++++ 6 files changed, 347 insertions(+), 4 deletions(-) create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp index 4d09043b1623..c8fbfeaeb451 100644 --- a/test/libevmasm/PlainAssemblyParser.cpp +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -39,11 +39,16 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou { m_sourceStream = std::istringstream(_source); m_sourceName = std::move(_sourceName); - Json codeJSON = Json::array(); m_lineNumber = 0; - if (!m_line.has_value()) - advanceLine(); + advanceLine(); + return parseAssembly(0); +} + +Json PlainAssemblyParser::parseAssembly(size_t _nestingLevel) +{ + Json assemblyJSON = {{".code", Json::array()}}; + Json& codeJSON = assemblyJSON[".code"]; while (m_line.has_value()) { @@ -52,6 +57,25 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou advanceLine(); continue; } + + size_t newLevel = parseNestingLevel(); + if (newLevel > _nestingLevel) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Indentation does not match the current subassembly nesting level."))); + + if (newLevel < _nestingLevel) + return assemblyJSON; + + if (currentToken().value == ".sub") + { + advanceLine(); + + std::string nextDataIndex = std::to_string(assemblyJSON[".data"].size()); + assemblyJSON[".data"][nextDataIndex] = parseAssembly(_nestingLevel + 1); + continue; + } + else if (assemblyJSON.contains(".data")) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The code of an assembly must be specified before its subassemblies."))); + if (c_instructions.contains(currentToken().value)) { expectNoMoreArguments(); @@ -91,7 +115,21 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou advanceLine(); } - return {{".code", codeJSON}}; + + return assemblyJSON; +} + +size_t PlainAssemblyParser::parseNestingLevel() const +{ + std::string_view indentationString = indentation(); + + if (indentationString != std::string(indentationString.size(), ' ')) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Non-space characters used for indentation."))); + + if (indentationString.size() % 4 != 0) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Each indentation level must consist of 4 spaces."))); + + return indentationString.size() / 4; } PlainAssemblyParser::Token const& PlainAssemblyParser::currentToken() const @@ -106,6 +144,16 @@ PlainAssemblyParser::Token const& PlainAssemblyParser::nextToken() const return m_lineTokens[m_tokenIndex + 1]; } +std::string_view PlainAssemblyParser::indentation() const +{ + soltestAssert(m_line.has_value()); + + if (m_lineTokens.empty()) + return *m_line; + + return std::string_view(*m_line).substr(0, m_lineTokens.at(0).position); +} + bool PlainAssemblyParser::advanceToken() { if (!hasMoreTokens()) diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h index 95cc3ee8f84e..5332b3202f7b 100644 --- a/test/libevmasm/PlainAssemblyParser.h +++ b/test/libevmasm/PlainAssemblyParser.h @@ -37,12 +37,18 @@ namespace solidity::evmasm::test /// - A non-empty line represents a single assembly item. /// - The name of the item is the first thing on the line and may consist of one or more tokens. /// - One or more arguments follow the name. +/// - Indentation determines assembly nesting level (4 spaces per level). +/// - A new subassembly starts with '.sub' and contains all subsequent lines at a higher nesting level. +/// The first line at the same or lower nesting level ends the subassembly. +/// - Subassemblies can be nested to arbitrary depth. +/// - The code of an assembly must be specified before its subassemblies. /// /// Supported items: /// - All instruction names. /// - PUSH /// - PUSH [tag] /// - tag +/// - .sub class PlainAssemblyParser { public: @@ -57,10 +63,15 @@ class PlainAssemblyParser size_t position; ///< Position of the first character of the token within m_line. }; + Json parseAssembly(size_t _nestingLevel); + size_t parseNestingLevel() const; + Token const& currentToken() const; Token const& nextToken() const; bool hasMoreTokens() const { return m_tokenIndex + 1 < m_lineTokens.size(); } + std::string_view indentation() const; + bool advanceToken(); std::string_view expectArgument(); void expectNoMoreArguments(); diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm new file mode 100644 index 000000000000..a3c0ef5396a1 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm @@ -0,0 +1,10 @@ +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [] +// } +// Assembly: +// Bytecode: +// Opcodes: +// SourceMappings: diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm new file mode 100644 index 000000000000..7dc1a515067d --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm @@ -0,0 +1,69 @@ +PUSH 0x2 +DUP1 +ADD + +.sub + PUSH 0x42 + DUP1 + MUL + +.sub + STOP +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH", +// "value": "2" +// }, +// { +// "name": "DUP1" +// }, +// { +// "name": "ADD" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "PUSH", +// "value": "42" +// }, +// { +// "name": "DUP1" +// }, +// { +// "name": "MUL" +// } +// ] +// }, +// "1": { +// ".code": [ +// { +// "name": "STOP" +// } +// ] +// } +// } +// } +// Assembly: +// 0x02 +// dup1 +// add +// stop +// +// sub_0: assembly { +// 0x42 +// dup1 +// mul +// } +// +// sub_1: assembly { +// stop +// } +// Bytecode: 60028001fe +// Opcodes: PUSH1 0x2 DUP1 ADD INVALID +// SourceMappings: :::-:0;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm new file mode 100644 index 000000000000..8914710dbf34 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm @@ -0,0 +1,34 @@ +.sub +.sub +.sub +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [], +// ".data": { +// "0": { +// ".code": [] +// }, +// "1": { +// ".code": [] +// }, +// "2": { +// ".code": [] +// } +// } +// } +// Assembly: +// stop +// +// sub_0: assembly { +// } +// +// sub_1: assembly { +// } +// +// sub_2: assembly { +// } +// Bytecode: fe +// Opcodes: INVALID +// SourceMappings: diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm new file mode 100644 index 000000000000..59beb9b69ece --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm @@ -0,0 +1,171 @@ +TIMESTAMP +TIMESTAMP + +.sub + TIMESTAMP + + .sub + TIMESTAMP + .sub + TIMESTAMP + .sub + TIMESTAMP + .sub + TIMESTAMP + .sub + TIMESTAMP +.sub + NUMBER + SLOAD + .sub + NUMBER + MLOAD + .sub + NUMBER + TLOAD + +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "TIMESTAMP" +// }, +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ] +// }, +// "1": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ] +// } +// } +// } +// } +// }, +// "2": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ] +// } +// } +// }, +// "1": { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "SLOAD" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "MLOAD" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "TLOAD" +// } +// ] +// } +// } +// } +// } +// } +// } +// } +// Assembly: +// timestamp +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// } +// +// sub_1: assembly { +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// } +// } +// } +// +// sub_2: assembly { +// timestamp +// } +// } +// +// sub_1: assembly { +// sload(number) +// stop +// +// sub_0: assembly { +// mload(number) +// stop +// +// sub_0: assembly { +// tload(number) +// } +// } +// } +// Bytecode: 4242fe +// Opcodes: TIMESTAMP TIMESTAMP INVALID +// SourceMappings: :::-:0; From 202933bf14e3bd8349416f3cd185dfda488ef33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Apr 2025 07:58:58 +0200 Subject: [PATCH 073/121] PlainAssemblyParser: Support pushing assembly sizes and offsets --- test/libevmasm/PlainAssemblyParser.cpp | 15 +++- test/libevmasm/PlainAssemblyParser.h | 2 + .../isoltestTesting/pushsize.asm | 33 +++++++++ .../isoltestTesting/pushsubsize.asm | 72 +++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp index c8fbfeaeb451..07b680474cb9 100644 --- a/test/libevmasm/PlainAssemblyParser.cpp +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -76,7 +76,7 @@ Json PlainAssemblyParser::parseAssembly(size_t _nestingLevel) else if (assemblyJSON.contains(".data")) BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The code of an assembly must be specified before its subassemblies."))); - if (c_instructions.contains(currentToken().value)) + if (c_instructions.contains(currentToken().value) || currentToken().value == "PUSHSIZE") { expectNoMoreArguments(); codeJSON.push_back({{"name", currentToken().value}}); @@ -90,6 +90,19 @@ Json PlainAssemblyParser::parseAssembly(size_t _nestingLevel) expectNoMoreArguments(); codeJSON.push_back({{"name", "PUSH [tag]"}, {"value", tagID}}); } + else if (hasMoreTokens() && (nextToken().value == "[$]" || nextToken().value == "#[$]")) + { + std::string pushType = std::string(nextToken().value); + advanceToken(); + std::string_view subassemblyID = expectArgument(); + expectNoMoreArguments(); + + if (!subassemblyID.starts_with("0x")) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The subassembly ID must be a hex number prefixed with '0x'."))); + + subassemblyID.remove_prefix("0x"s.size()); + codeJSON.push_back({{"name", "PUSH " + pushType}, {"value", subassemblyID}}); + } else { std::string_view immediateArgument = expectArgument(); diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h index 5332b3202f7b..9318d1662389 100644 --- a/test/libevmasm/PlainAssemblyParser.h +++ b/test/libevmasm/PlainAssemblyParser.h @@ -48,6 +48,8 @@ namespace solidity::evmasm::test /// - PUSH /// - PUSH [tag] /// - tag +/// - PUSH [$] +/// - PUSH #[$] /// - .sub class PlainAssemblyParser { diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm new file mode 100644 index 000000000000..3c92687c425a --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm @@ -0,0 +1,33 @@ +PUSHSIZE + +.sub + PUSHSIZE +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSHSIZE" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "PUSHSIZE" +// } +// ] +// } +// } +// } +// Assembly: +// bytecodeSize +// stop +// +// sub_0: assembly { +// bytecodeSize +// } +// Bytecode: 6003fe +// Opcodes: PUSH1 0x3 INVALID +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm new file mode 100644 index 000000000000..1b51c22a84ef --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm @@ -0,0 +1,72 @@ +PUSH [$] 0x0000 +PUSH #[$] 0x0000 + +.sub + PUSH [$] 0x0 + PUSH #[$] 0x2 + + .sub + .sub + .sub +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH [$]", +// "value": "0000" +// }, +// { +// "name": "PUSH #[$]", +// "value": "0000" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "PUSH [$]", +// "value": "0" +// }, +// { +// "name": "PUSH #[$]", +// "value": "2" +// } +// ], +// ".data": { +// "0": { +// ".code": [] +// }, +// "1": { +// ".code": [] +// }, +// "2": { +// ".code": [] +// } +// } +// } +// } +// } +// Assembly: +// dataOffset(sub_0) +// dataSize(sub_0) +// stop +// +// sub_0: assembly { +// dataOffset(sub_0) +// dataSize(sub_2) +// stop +// +// sub_0: assembly { +// } +// +// sub_1: assembly { +// } +// +// sub_2: assembly { +// } +// } +// Bytecode: 60056005fe60056000fe +// Opcodes: PUSH1 0x5 PUSH1 0x5 INVALID PUSH1 0x5 PUSH1 0x0 INVALID +// SourceMappings: :::-:0; From 78107e344ce526695a5a989250d01812a248d536 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Sun, 27 Apr 2025 11:01:00 +0200 Subject: [PATCH 074/121] Assembly item asserts that it's not implicity constructed by instruction for swapn/dupn --- libevmasm/AssemblyItem.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 0dfe0749768a..8386bf2dd4bc 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -85,7 +85,10 @@ class AssemblyItem m_type(Operation), m_instruction(_i), m_debugData(std::move(_debugData)) - {} + { + solAssert(_i != Instruction::SWAPN, "Construct via AssemblyItem::swapN"); + solAssert(_i != Instruction::DUPN, "Construct via AssemblyItem::dupN"); + } AssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()): m_type(_type), m_debugData(std::move(_debugData)) From 49c2e551c12f8fde4dccd59d07be0ad5637060dd Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 28 Apr 2025 17:57:02 -0300 Subject: [PATCH 075/121] Set prague as EVM default version --- .circleci/config.yml | 2 +- .circleci/soltest_all.sh | 2 +- Changelog.md | 1 + docs/using-the-compiler.rst | 8 ++--- liblangutil/EVMVersion.h | 2 +- scripts/externalTests/common.sh | 2 +- scripts/externalTests/runners/base.py | 2 +- scripts/tests.sh | 2 +- .../mcopy_bytes_array_abi_decode/args | 2 +- .../args | 2 +- .../args | 2 +- test/cmdlineTests/metadata/output | 2 +- .../standard_metadata/output.json | 2 +- .../output.json | 2 +- .../output.json | 2 +- .../output.json | 2 +- .../output.json | 4 +-- .../output | 2 +- .../output | 2 +- test/libsolidity/StandardCompiler.cpp | 32 ++++--------------- 20 files changed, 30 insertions(+), 47 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 09b1281c5630..80b3c5358825 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:98f963ed799a0d206ef8e7b5475f847e0dea53b7fdea9618bbc6106a62730bd2" evm-version: type: string - default: cancun + default: prague orbs: win: circleci/windows@2.2.0 diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 216b1ee3815a..56aa1c3be640 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -38,7 +38,7 @@ EVMS_WITH_EOF=(osaka) # set EVM_VALUES to the default values. IFS=" " read -ra EVM_VALUES <<< "${1:-${DEFAULT_EVM_VALUES[@]}}" -DEFAULT_EVM=cancun +DEFAULT_EVM=prague OPTIMIZE_VALUES=(0 1) EOF_VERSIONS=(0 1) diff --git a/Changelog.md b/Changelog.md index e8ccbb525302..cbaa4252151c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: +* EVM: Set default EVM Version to `prague`. * NatSpec: Capture Natspec documentation of `enum` values in the AST. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 23e83baec4e6..a3943ea94da2 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -176,12 +176,12 @@ at each version. Backward compatibility is not guaranteed between each version. - Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 `_). - ``shanghai`` - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 `_). -- ``cancun`` (**default**) +- ``cancun`` - The block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly. - Introduces ``blobhash()`` in inline assembly and a corresponding global function to retrieve versioned hashes of blobs associated with the transaction (see `EIP-4844 `_). - Opcode ``mcopy`` is available in assembly (see `EIP-5656 `_). - Opcodes ``tstore`` and ``tload`` are available in assembly (see `EIP-1153 `_). -- ``prague`` (**experimental**) +- ``prague`` (**default**) - ``osaka`` (**experimental**) - Experimental compilation to EOF is available starting from this version. (`EIP-7692 `_) @@ -356,8 +356,8 @@ Input Description // Version of the EVM to compile for (optional). // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, - // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default), prague (experimental) or osaka (experimental). - "evmVersion": "cancun", + // petersburg, istanbul, berlin, london, paris, shanghai, cancun, prague (default) or osaka (experimental). + "evmVersion": "prague", // EVM Object Format version to compile for (optional, experimental). // Currently the only valid value is 1. If not specified, legacy non-EOF bytecode will be generated. "eofVersion": null, diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index a159f2e4bb2f..38580621a45e 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -167,7 +167,7 @@ class EVMVersion: EVMVersion(Version _version): m_version(_version) {} - Version m_version = Version::Cancun; + Version m_version = Version::Prague; }; } diff --git a/scripts/externalTests/common.sh b/scripts/externalTests/common.sh index 2983b30c296a..26f27b07baca 100644 --- a/scripts/externalTests/common.sh +++ b/scripts/externalTests/common.sh @@ -22,7 +22,7 @@ set -e # Requires $REPO_ROOT to be defined and "${REPO_ROOT}/scripts/common.sh" to be included before. -CURRENT_EVM_VERSION=cancun +CURRENT_EVM_VERSION=prague AVAILABLE_PRESETS=( legacy-no-optimize diff --git a/scripts/externalTests/runners/base.py b/scripts/externalTests/runners/base.py index 4778206150e2..20ba67ddb4a4 100644 --- a/scripts/externalTests/runners/base.py +++ b/scripts/externalTests/runners/base.py @@ -41,7 +41,7 @@ from test_helpers import settings_from_preset from test_helpers import SettingsPreset -CURRENT_EVM_VERSION: str = "cancun" +CURRENT_EVM_VERSION: str = "prague" @dataclass class TestConfig: diff --git a/scripts/tests.sh b/scripts/tests.sh index 3d2849369eca..5ff962be6506 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -115,7 +115,7 @@ do for vm in $EVM_VERSIONS do FORCE_ABIV1_RUNS="no" - if [[ "$vm" == "cancun" ]] + if [[ "$vm" == "prague" ]] then FORCE_ABIV1_RUNS="no yes" # run both in paris fi diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/args b/test/cmdlineTests/mcopy_bytes_array_abi_decode/args index 4a03d8d932b9..a346a1eb7963 100644 --- a/test/cmdlineTests/mcopy_bytes_array_abi_decode/args +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/args @@ -1 +1 @@ ---evm-version cancun --no-cbor-metadata --via-ir --ir --debug-info none +--no-cbor-metadata --via-ir --ir --debug-info none diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args index c74711ba8aec..a582f88e9c3d 100644 --- a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args @@ -1 +1 @@ ---evm-version cancun --no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none +--no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/args b/test/cmdlineTests/mcopy_string_literal_returned_from_function/args index c74711ba8aec..a582f88e9c3d 100644 --- a/test/cmdlineTests/mcopy_string_literal_returned_from_function/args +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/args @@ -1 +1 @@ ---evm-version cancun --no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none +--no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none diff --git a/test/cmdlineTests/metadata/output b/test/cmdlineTests/metadata/output index 0910128894df..a62f2ed145f8 100644 --- a/test/cmdlineTests/metadata/output +++ b/test/cmdlineTests/metadata/output @@ -1,4 +1,4 @@ ======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"prague","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} diff --git a/test/cmdlineTests/standard_metadata/output.json b/test/cmdlineTests/standard_metadata/output.json index 5b9c8504f386..155e15db1761 100644 --- a/test/cmdlineTests/standard_metadata/output.json +++ b/test/cmdlineTests/standard_metadata/output.json @@ -2,7 +2,7 @@ "contracts": { "C": { "C": { - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}" + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}" } } }, diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json index c461a1485bda..07087b30fdb3 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json @@ -2,7 +2,7 @@ "contracts": { "A": { "C": { - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" } } }, diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json index c461a1485bda..07087b30fdb3 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json @@ -2,7 +2,7 @@ "contracts": { "A": { "C": { - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" } } }, diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json index 0fa7fcff3cda..eae7a321f05b 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json @@ -32,7 +32,7 @@ "x()": "0c55699c" } }, - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"x\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x67a13ebd685e4c6f792e71eb747dac57edb99e94d04d841ee6c979ae517934ce\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://665b000da768823654f680d02686c1e59d682a0b3882e43a77fed9f80ce64ae8\",\"dweb:/ipfs/QmVnKvuidH6KiCdNQpoAQUtDbB8hXkafVLXWMNitUcxnqC\"]}},\"version\":1}", + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"x\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x67a13ebd685e4c6f792e71eb747dac57edb99e94d04d841ee6c979ae517934ce\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://665b000da768823654f680d02686c1e59d682a0b3882e43a77fed9f80ce64ae8\",\"dweb:/ipfs/QmVnKvuidH6KiCdNQpoAQUtDbB8hXkafVLXWMNitUcxnqC\"]}},\"version\":1}", "storageLayout": { "storage": [], "types": null diff --git a/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json b/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json index 3869f7c652bd..be87a5176d06 100644 --- a/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json +++ b/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json @@ -35,7 +35,7 @@ "irAst": null, "irOptimized": "", "irOptimizedAst": null, - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", "storageLayout": { "storage": [], "types": null @@ -84,7 +84,7 @@ "irAst": null, "irOptimized": "", "irOptimizedAst": null, - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"I\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"I\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", "storageLayout": { "storage": [], "types": null diff --git a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output index 744bc03a8c6e..de60e7d1dcd8 100644 --- a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output +++ b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output @@ -1,4 +1,4 @@ ======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"prague","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} diff --git a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output index a7b037775f2c..2b32c23ee319 100644 --- a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output @@ -130,4 +130,4 @@ object "C_28" { } Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"prague","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index b17f566613a1..5360a2778677 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1170,33 +1171,14 @@ BOOST_AUTO_TEST_CASE(evm_version) )"; }; Json result; - result = compile(inputForVersion("\"evmVersion\": \"homestead\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"homestead\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"tangerineWhistle\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"tangerineWhistle\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"spuriousDragon\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"spuriousDragon\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"byzantium\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"byzantium\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"constantinople\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"constantinople\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"petersburg\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"petersburg\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"istanbul\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"istanbul\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"berlin\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"berlin\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"london\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"london\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"paris\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"paris\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"shanghai\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"shanghai\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"cancun\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"cancun\"") != std::string::npos); + for (auto const& version: langutil::EVMVersion::allVersions()) + { + result = compile(inputForVersion(fmt::format("\"evmVersion\": \"{}\",", version.name()))); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find(fmt::format("\"evmVersion\":\"{}\"", version.name())) != std::string::npos); + } // test default result = compile(inputForVersion("")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"cancun\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"prague\"") != std::string::npos); // test invalid result = compile(inputForVersion("\"evmVersion\": \"invalid\",")); BOOST_CHECK(result["errors"][0]["message"].get() == "Invalid EVM version requested."); From ca699f9b02a59270afd8f43c28d15c9a63d301ff Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 6 May 2025 11:47:39 -0300 Subject: [PATCH 076/121] bump hardhat version --- test/externalTests/gp2.sh | 5 +---- test/externalTests/pool-together.sh | 4 +--- test/externalTests/uniswap.sh | 5 +---- test/externalTests/zeppelin.sh | 5 +---- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/test/externalTests/gp2.sh b/test/externalTests/gp2.sh index 20ea586f5f09..d648de592058 100755 --- a/test/externalTests/gp2.sh +++ b/test/externalTests/gp2.sh @@ -66,10 +66,7 @@ function gp2_test force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" force_hardhat_unlimited_contract_size "$config_file" "$config_var" yarn - # We require to install hardhat 2.20.0 due to support for evm version cancun, otherwise we get the following error: - # Invalid value {"blockGasLimit":12500000,"hardfork":"cancun","allowUnlimitedContractSize":true} for HardhatConfig.networks.hardhat - Expected a value of type HardhatNetworkConfig. - # See: https://github.com/NomicFoundation/hardhat/issues/4176 - yarn add hardhat@2.20.0 + yarn add hardhat # Ignore bench directory which fails to compile with current hardhat and ethers versions. # bench/trace/gas.ts:123:19 - error TS2339: Property 'equals' does not exist on type 'Uint8Array'. diff --git a/test/externalTests/pool-together.sh b/test/externalTests/pool-together.sh index 0fc8aafbd69d..2eb47912c8b1 100755 --- a/test/externalTests/pool-together.sh +++ b/test/externalTests/pool-together.sh @@ -66,9 +66,7 @@ function pool_together_test force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" yarn install - # Hardhat 2.20.0 is the last version that works. Newer versions throw this error: - # Unexpected config HardhatConfig.networks.hardhat.initialBaseFeePerGas found - This field is only valid for networks with EIP-1559. Try a newer hardfork or remove it. - yarn add hardhat@2.20.0 + yarn add hardhat # These come with already compiled artifacts. We want them recompiled with latest compiler. rm -r node_modules/@pooltogether/yield-source-interface/artifacts/ diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index f3d78e6e3397..575fcf309cd2 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -90,10 +90,7 @@ function uniswap_test # TODO: Remove when https://github.com/ethers-io/ethers.js/discussions/2849 is resolved. pnpm install ethers@5.6.1 - # We set hardhat version to 2.20.0 since version 2.21.0 has issues with solidity-coverage plugin - # that often causes out-of-memory errors. - # See hardhat note about the issue here: https://github.com/NomicFoundation/hardhat/releases/tag/hardhat@2.21.0 - pnpm install hardhat@2.20.0 + pnpm install hardhat replace_version_pragmas diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index b9e65562e08f..86d2495da30b 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -105,10 +105,7 @@ function zeppelin_test force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" npm install - # We require to install hardhat 2.20.0 due to support for evm version cancun, otherwise we get the following error: - # Invalid value {"blockGasLimit":10000000,"allowUnlimitedContractSize":true,"hardfork":"cancun"} for HardhatConfig.networks.hardhat - Expected a value of type HardhatNetworkConfig. - # See: https://github.com/NomicFoundation/hardhat/issues/4176 - npm install hardhat@2.20.0 + npm install hardhat replace_version_pragmas for preset in $SELECTED_PRESETS; do From 24d534f67009c62feb336940e6711526d0905390 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 6 May 2025 14:59:13 -0300 Subject: [PATCH 077/121] Increase resource for uniswap ext test --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 80b3c5358825..6c88b9d19f7c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -831,6 +831,7 @@ defaults: project: uniswap binary_type: native image: cimg/node:18.16 + resource_class: medium # Tests run out of memory on a smaller machine - job_native_test_ext_prb_math: &job_native_test_ext_prb_math <<: *requires_b_ubu_static From 13d734fd22990508a256c4c591310e78b8247112 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 6 May 2025 17:24:18 -0300 Subject: [PATCH 078/121] Workaround for openzepellin ext test --- test/externalTests/zeppelin.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 86d2495da30b..9bc3e29132aa 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -101,6 +101,10 @@ function zeppelin_test # Here only the testToInt(248) and testToInt(256) cases fail so change the loop range to skip them sed -i "s|range(8, 256, 8)\(.forEach(bits => testToInt(bits));\)|range(8, 240, 8)\1|" test/utils/math/SafeCast.test.js + # TODO: Remove when next hardhat version releases, the fix is already merged: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5663 + # Fails with ProviderError: Invalid transaction: GasFloorMoreThanGasLimit + sed -i "177s|+ 2_000n|+ 10_000n|" test/metatx/ERC2771Forwarder.test.js + neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" From 1e6842c2c312a124c8ffb28fa0097ebd58f5e990 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 7 May 2025 09:39:30 +0200 Subject: [PATCH 079/121] Fix broken docs links --- docs/contracts/inheritance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst index fccfee609587..8a2d12afd839 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -548,7 +548,7 @@ Multiple Inheritance and Linearization Languages that allow multiple inheritance have to deal with several problems. One is the `Diamond Problem `_. -Solidity is similar to Python in that it uses "`C3 Linearization `_" +Solidity is similar to Python in that it uses C3 Linearization to force a specific order in the directed acyclic graph (DAG) of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in From 1c8d4016f5394d9804864339515b995210eaff5a Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 7 May 2025 10:46:23 +0200 Subject: [PATCH 080/121] Set changelog release date --- 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 cbaa4252151c..9a1139e9ce84 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,4 @@ -### 0.8.30 (unreleased) - -Language Features: - +### 0.8.30 (2025-05-07) Compiler Features: * EVM: Set default EVM Version to `prague`. diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 60fcdd049a0f..1a210b885c2a 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1923,6 +1923,10 @@ ], "released": "2021-03-23" }, + "0.8.30": { + "bugs": [], + "released": "2025-05-07" + }, "0.8.4": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", From 64ca6a07ac62a31de0bc28761d1884bac0910ce3 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 081/121] 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 (cherry picked from commit 2ab47bdc5bd5c2fe6263c3656791264392ad89bd) --- 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 321f5151fcf1c0ca203532ed8162950ca5fdbbdf 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 082/121] 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 (cherry picked from commit 44cdd8d6a948bfef0696ab664ada75c0158fd427) --- 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 abb2fdd100aa..e1a278494b8a 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 28c6c0285efab1912431815baf99195e3e8cf6ca 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 083/121] 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 (cherry picked from commit 0495910d8a559a6c08b2812e8b9941ec79400ea4) --- 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 | 6 +- .../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 | 4 +- ...nested_array_element_memory_to_storage.sol | 4 +- ...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 | 18 +- .../memory_to_storage.sol | 12 +- .../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, 1511 insertions(+), 286 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 d52ad6b9c48a..0a0ec6a879a1 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 761feebec9d5..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: 92740 -// gas legacy: 93035 -// gas legacyOptimized: 92257 +// 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 13cb9c28fd26..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: 92800 -// gas legacy: 93006 -// gas legacyOptimized: 92261 +// gas irOptimized: 74044 +// gas legacy: 75528 +// gas legacyOptimized: 73861 // g() -> 0 // h() -> 0 -// gas irOptimized: 92862 -// gas legacy: 93028 -// gas legacyOptimized: 92303 +// 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 2fccff774e94..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: 90001 -// gas legacyOptimized: 89085 +// 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 0a2bcffce201..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: 93858 -// gas legacy: 97451 -// gas legacyOptimized: 94200 +// 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 2bb3bcf333e3..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: 104178 +// 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 af2983b066bd..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 @@ -10,9 +10,9 @@ 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 legacy: 103509 -// gas legacyOptimized: 101266 +// gas irOptimized: 95505 +// 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 fe758fe8fd13..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: 59345 -// gas legacyOptimized: 57279 +// 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 5040a72cadb5..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 @@ -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: 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 2f4b4ca7c9a1..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 @@ -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: 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 9665201c98fd..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: 90992 -// gas legacy: 111037 -// gas legacyOptimized: 109633 +// 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 ebe2186fd60f..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: 122148 -// gas legacy: 122440 -// gas legacyOptimized: 122259 +// 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 57bf38e52c6b..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: 117101 +// 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 2345fea3cfe2..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: 111570 +// 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 c3d58811ae4e..0815a2da7ace 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: 44982 // 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: 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: 69174 -// gas legacy: 75156 -// gas legacyOptimized: 74342 +// gas irOptimized: 68635 +// 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 db745dce31ec..40005a035735 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol @@ -28,14 +28,14 @@ contract C { // gas legacyOptimized: 44671 // 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: 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: 69617 -// gas legacy: 76238 -// gas legacyOptimized: 74921 +// gas irOptimized: 68937 +// 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 3e46de97dce0b25cd2bf9989fd8f28f643cacadd Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 12 Feb 2026 15:20:02 +0100 Subject: [PATCH 084/121] Test cases (cherry picked from commit d38b746194f647f964a55d1c7072c2f3b8217d51) --- .../args | 1 + .../input.sol | 15 ++ .../output | 214 ++++++++++++++++++ ...fter_inherited_storage_same_value_type.sol | 26 +++ ...storage_mapping_delete_same_value_type.sol | 23 ++ ..._storage_struct_delete_same_value_type.sol | 28 +++ ...fore_inherited_storage_same_value_type.sol | 26 +++ ...storage_mapping_delete_same_value_type.sol | 23 ++ ..._storage_struct_delete_same_value_type.sol | 28 +++ ...storage_bool_array_transient_uint256_1.sol | 26 +++ ...storage_bool_array_transient_uint256_2.sol | 26 +++ .../delete_storage_u256_transient_u256_1.sol | 22 ++ .../delete_storage_u256_transient_u256_2.sol | 22 ++ 13 files changed, 480 insertions(+) create mode 100644 test/cmdlineTests/storage_transient_storage_collision_ir_output/args create mode 100644 test/cmdlineTests/storage_transient_storage_collision_ir_output/input.sol create mode 100644 test/cmdlineTests/storage_transient_storage_collision_ir_output/output create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_1.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_2.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_1.sol create mode 100644 test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_2.sol diff --git a/test/cmdlineTests/storage_transient_storage_collision_ir_output/args b/test/cmdlineTests/storage_transient_storage_collision_ir_output/args new file mode 100644 index 000000000000..b7ec904f1024 --- /dev/null +++ b/test/cmdlineTests/storage_transient_storage_collision_ir_output/args @@ -0,0 +1 @@ +--ir-optimized --evm-version cancun --debug-info none diff --git a/test/cmdlineTests/storage_transient_storage_collision_ir_output/input.sol b/test/cmdlineTests/storage_transient_storage_collision_ir_output/input.sol new file mode 100644 index 000000000000..e7d3930152fa --- /dev/null +++ b/test/cmdlineTests/storage_transient_storage_collision_ir_output/input.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + uint256 transient varTransient; + uint256 public varStorage = 0xeeeeeeeeee; + + function foo() external returns (uint256) { + varTransient = 0xffffffff; + delete varTransient; + delete varStorage; + + return varStorage; + } +} diff --git a/test/cmdlineTests/storage_transient_storage_collision_ir_output/output b/test/cmdlineTests/storage_transient_storage_collision_ir_output/output new file mode 100644 index 000000000000..e3a251b2d8b0 --- /dev/null +++ b/test/cmdlineTests/storage_transient_storage_collision_ir_output/output @@ -0,0 +1,214 @@ +Optimized IR: +/// @use-src 0:"input.sol" +object "C_25" { + code { + { + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + constructor_C() + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_25_deployed"), datasize("C_25_deployed")) + return(_1, datasize("C_25_deployed")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function shift_left(value) -> newValue + { newValue := shl(0, value) } + function update_byte_slice_shift(value, toInsert) -> result + { + let mask := not(0) + toInsert := shift_left(toInsert) + value := and(value, not(mask)) + result := or(value, and(toInsert, mask)) + } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function prepare_store_uint256(value) -> ret + { ret := value } + function update_storage_value_offset_rational_by_to_uint256(slot, value) + { + let convertedValue := convert_rational_by_to_uint256(value) + sstore(slot, update_byte_slice_shift(sload(slot), prepare_store_uint256(convertedValue))) + } + function constructor_C() + { + let expr := 0xeeeeeeeeee + update_storage_value_offset_rational_by_to_uint256(0x00, expr) + } + } + /// @use-src 0:"input.sol" + object "C_25_deployed" { + code { + { + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xc2985578 { external_fun_foo() } + case 0xff2558ff { external_fun_varStorage() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function abi_decode(headStart, dataEnd) + { + if slt(sub(dataEnd, headStart), 0) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function abi_encode_uint256_to_uint256(value, pos) + { + mstore(pos, cleanup_uint256(value)) + } + function abi_encode_uint256(headStart, value0) -> tail + { + tail := add(headStart, 32) + abi_encode_uint256_to_uint256(value0, add(headStart, 0)) + } + function external_fun_foo() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + abi_decode(4, calldatasize()) + let ret := fun_foo() + let memPos := allocate_unbounded() + let memEnd := abi_encode_uint256(memPos, ret) + return(memPos, sub(memEnd, memPos)) + } + function shift_right_unsigned_dynamic(bits, value) -> newValue + { newValue := shr(bits, value) } + function cleanup_from_storage_uint256(value) -> cleaned + { cleaned := value } + function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value + { + value := cleanup_from_storage_uint256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value)) + } + function read_from_storage_split_dynamic_uint256(slot, offset) -> value + { + value := extract_from_storage_value_dynamict_uint256(sload(slot), offset) + } + function getter_fun_varStorage() -> ret + { + let slot := 0 + let offset := 0 + ret := read_from_storage_split_dynamic_uint256(slot, offset) + } + function external_fun_varStorage() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + abi_decode(4, calldatasize()) + let ret := getter_fun_varStorage() + let memPos := allocate_unbounded() + let memEnd := abi_encode_uint256(memPos, ret) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function zero_value_for_split_uint256() -> ret + { ret := 0 } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function shift_left(value) -> newValue + { newValue := shl(0, value) } + function update_byte_slice_shift(value, toInsert) -> result + { + let mask := not(0) + toInsert := shift_left(toInsert) + value := and(value, not(mask)) + result := or(value, and(toInsert, mask)) + } + function convert_uint256_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_uint256(value))) + } + function prepare_store_uint256(value) -> ret + { ret := value } + function update_transient_storage_value_offset_uint256_to_uint256(slot, value) + { + let convertedValue := convert_uint256_to_uint256(value) + tstore(slot, update_byte_slice_shift(tload(slot), prepare_store_uint256(convertedValue))) + } + function shift_left_dynamic(bits, value) -> newValue + { newValue := shl(bits, value) } + function update_byte_slice_dynamic32(value, shiftBytes, toInsert) -> result + { + let shiftBits := mul(shiftBytes, 8) + let mask := shift_left_dynamic(shiftBits, not(0)) + toInsert := shift_left_dynamic(shiftBits, toInsert) + value := and(value, not(mask)) + result := or(value, and(toInsert, mask)) + } + function update_transient_storage_value_uint256_to_uint256(slot, offset, value) + { + let convertedValue := convert_uint256_to_uint256(value) + tstore(slot, update_byte_slice_dynamic32(tload(slot), offset, prepare_store_uint256(convertedValue))) + } + function storage_set_to_zero_uint256(slot, offset) + { + let zero := zero_value_for_split_uint256() + update_transient_storage_value_uint256_to_uint256(slot, offset, zero) + } + function shift_right_0_unsigned(value) -> newValue + { newValue := shr(0, value) } + function extract_from_storage_value_offset_uint256(slot_value) -> value + { + value := cleanup_from_storage_uint256(shift_right_0_unsigned(slot_value)) + } + function read_from_storage_split_offset_uint256(slot) -> value + { + value := extract_from_storage_value_offset_uint256(sload(slot)) + } + function fun_foo() -> var + { + let zero_uint256 := zero_value_for_split_uint256() + var := zero_uint256 + let expr := 0xffffffff + let _1 := convert_rational_by_to_uint256(expr) + update_transient_storage_value_offset_uint256_to_uint256(0x00, _1) + storage_set_to_zero_uint256(0x00, 0) + storage_set_to_zero_uint256(0x00, 0) + let _2 := read_from_storage_split_offset_uint256(0x00) + let expr_1 := _2 + var := expr_1 + leave + } + } + data ".metadata" hex"" + } +} diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol new file mode 100644 index 000000000000..f4badbc98845 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol @@ -0,0 +1,26 @@ +contract Base { + uint256 public x; + + function deleteX() internal { + delete x; + } +} + +contract C is Base { + uint256 transient t; + + function setAndClear() external { + x = 1; + t = 2; + deleteX(); + delete t; + assert(t == 0); + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// setAndClear() -> +// x() -> 1 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol new file mode 100644 index 000000000000..b1a38832158d --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol @@ -0,0 +1,23 @@ +contract C { + mapping(uint256 => uint256) m; + uint256 transient t; + + function setAndClear() external { + m[0] = 1; + t = 2; + delete m[0]; + delete t; + assert(t == 2); + } + + function getM() external view returns (uint256) { + return m[0]; + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// setAndClear() -> +// getM() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol new file mode 100644 index 000000000000..33a0dc2de46b --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol @@ -0,0 +1,28 @@ +contract C { + struct S { + uint256 a; + address b; + } + + S s; + uint256 transient t; + + function setAndDelete() external { + s.a = 1; + s.b = address(0x1234); + t = 2; + delete s; + delete t; + assert(t == 2); + } + + function getS() external view returns (uint256, address) { + return (s.a, s.b); + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// setAndDelete() -> +// getS() -> 0, 0 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol new file mode 100644 index 000000000000..8e40422a9019 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol @@ -0,0 +1,26 @@ +contract Base { + uint256 public x; + + function deleteX() internal { + delete x; + } +} + +contract C is Base { + uint256 transient t; + + function setAndClear() external { + x = 1; + t = 2; + delete t; + assert(t == 0); + deleteX(); + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// setAndClear() -> +// x() -> 1 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol new file mode 100644 index 000000000000..129fafad7507 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol @@ -0,0 +1,23 @@ +contract C { + mapping(uint256 => uint256) m; + uint256 transient t; + + function setAndClear() external { + m[0] = 1; + t = 2; + delete t; + assert(t == 0); + delete m[0]; + } + + function getM() external view returns (uint256) { + return m[0]; + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// setAndClear() -> +// getM() -> 1 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol new file mode 100644 index 000000000000..d499d0618374 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol @@ -0,0 +1,28 @@ +contract C { + struct S { + uint256 a; + address b; + } + + S s; + uint256 transient t; + + function setAndDelete() external { + s.a = 1; + s.b = address(0x1234); + t = 2; + delete t; + assert(t == 0); + delete s; + } + + function getS() external view returns (uint256, address) { + return (s.a, s.b); + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// setAndDelete() -> +// getS() -> 1, 0 diff --git a/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_1.sol b/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_1.sol new file mode 100644 index 000000000000..4d84b23f70e7 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_1.sol @@ -0,0 +1,26 @@ +pragma solidity >=0.0; + +contract C { + bool[3] flags = [true, true, true]; + uint256 transient temp; + + function f() external { + temp = 0xffffffff; + assert(temp == 0xffffffff); + delete temp; + delete flags; + } + + function getFlags() external returns(bool[3] memory) + { + return flags; + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// getFlags() -> true, true, true +// f() -> +// getFlags() -> true, true, true diff --git a/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_2.sol b/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_2.sol new file mode 100644 index 000000000000..f95b191c108c --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_2.sol @@ -0,0 +1,26 @@ +pragma solidity >=0.0; + +contract C { + bool[3] flags = [true, true, true]; + uint256 transient temp; + + function f() external { + temp = 0xffffffff; + assert(temp == 0xffffffff); + delete flags; + delete temp; + } + + function getFlags() external returns(bool[3] memory) + { + return flags; + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// getFlags() -> true, true, true +// f() -> +// getFlags() -> false, false, false diff --git a/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_1.sol b/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_1.sol new file mode 100644 index 000000000000..08f8120be0ce --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_1.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + uint256 transient varTransient; + uint256 public varStorage = 0xeeeeeeeeee; + + function foo() external { + varTransient = 0xffffffff; + assert(varTransient == 0xffffffff); + delete varTransient; + delete varStorage; + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// varStorage() -> 0xeeeeeeeeee +// foo() -> +// varStorage() -> 0xeeeeeeeeee diff --git a/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_2.sol b/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_2.sol new file mode 100644 index 000000000000..03e06747af1a --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_2.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + uint256 transient varTransient; + uint256 public varStorage = 0xeeeeeeeeee; + + function foo() external { + varTransient = 0xffffffff; + assert(varTransient == 0xffffffff); + delete varStorage; + delete varTransient; + } +} + +// ==== +// EVMVersion: >=cancun +// compileViaYul: true +// ---- +// varStorage() -> 0xeeeeeeeeee +// foo() -> +// varStorage() -> 0 From 06cf704ae433a0dcda6a570a844f0e3bdcebdb1e Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 12 Feb 2026 15:22:09 +0100 Subject: [PATCH 085/121] Fix transient/storage collision when deleting (cherry picked from commit c4dd9e407e01020c2bc1d1c70f4ffcf282ba7fd2) --- libsolidity/codegen/YulUtilFunctions.cpp | 17 ++++++++++- .../output | 14 +++++++-- ...fter_inherited_storage_same_value_type.sol | 3 +- ...rage_array_delete_different_base_type.sol} | 9 ++---- ...after_storage_array_pop_same_base_type.sol | 30 +++++++++++++++++++ ..._after_storage_delete_same_value_type.sol} | 10 ++----- ...storage_mapping_delete_same_value_type.sol | 3 +- ..._storage_struct_delete_same_value_type.sol | 8 ++--- ...fore_inherited_storage_same_value_type.sol | 3 +- ...rage_array_delete_different_base_type.sol} | 11 +++---- ...rray_partial_assignment_same_base_type.sol | 27 +++++++++++++++++ ...before_storage_delete_same_value_type.sol} | 12 +++----- ...storage_mapping_delete_same_value_type.sol | 3 +- ..._storage_struct_delete_same_value_type.sol | 8 ++--- 14 files changed, 109 insertions(+), 49 deletions(-) rename test/libsolidity/semanticTests/storage/{delete_storage_bool_array_transient_uint256_2.sol => delete_overlapping_transient_after_storage_array_delete_different_base_type.sol} (75%) create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_pop_same_base_type.sol rename test/libsolidity/semanticTests/storage/{delete_storage_u256_transient_u256_2.sol => delete_overlapping_transient_after_storage_delete_same_value_type.sol} (63%) rename test/libsolidity/semanticTests/storage/{delete_storage_bool_array_transient_uint256_1.sol => delete_overlapping_transient_before_storage_array_delete_different_base_type.sol} (67%) create mode 100644 test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_partial_assignment_same_base_type.sol rename test/libsolidity/semanticTests/storage/{delete_storage_u256_transient_u256_1.sol => delete_overlapping_transient_before_storage_delete_same_value_type.sol} (57%) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index e1a278494b8a..4c3cd8c0fc69 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -4361,7 +4361,22 @@ std::string YulUtilFunctions::zeroValueFunction(Type const& _type, bool _splitFu std::string YulUtilFunctions::storageSetToZeroFunction(Type const& _type, VariableDeclaration::Location _location) { - std::string const functionName = "storage_set_to_zero_" + _type.identifier(); + solAssert( + _location == VariableDeclaration::Location::Transient || + _location == VariableDeclaration::Location::Unspecified, + "Invalid location for the storage_set_to_zero function" + ); + + if (dynamic_cast(&_type)) + solAssert( + _location == VariableDeclaration::Location::Unspecified && + _type.dataStoredIn(DataLocation::Storage) + ); + + std::string const functionName = + (_location == VariableDeclaration::Location::Transient ? "transient_"s : "") + + "storage_set_to_zero_" + + _type.identifier(); return m_functionCollector.createFunction(functionName, [&]() { if (_type.isValueType()) diff --git a/test/cmdlineTests/storage_transient_storage_collision_ir_output/output b/test/cmdlineTests/storage_transient_storage_collision_ir_output/output index e3a251b2d8b0..dd8abeb333b0 100644 --- a/test/cmdlineTests/storage_transient_storage_collision_ir_output/output +++ b/test/cmdlineTests/storage_transient_storage_collision_ir_output/output @@ -179,11 +179,21 @@ object "C_25" { let convertedValue := convert_uint256_to_uint256(value) tstore(slot, update_byte_slice_dynamic32(tload(slot), offset, prepare_store_uint256(convertedValue))) } - function storage_set_to_zero_uint256(slot, offset) + function transient_storage_set_to_zero_uint256(slot, offset) { let zero := zero_value_for_split_uint256() update_transient_storage_value_uint256_to_uint256(slot, offset, zero) } + function update_storage_value_uint256_to_uint256(slot, offset, value) + { + let convertedValue := convert_uint256_to_uint256(value) + sstore(slot, update_byte_slice_dynamic32(sload(slot), offset, prepare_store_uint256(convertedValue))) + } + function storage_set_to_zero_uint256(slot, offset) + { + let zero := zero_value_for_split_uint256() + update_storage_value_uint256_to_uint256(slot, offset, zero) + } function shift_right_0_unsigned(value) -> newValue { newValue := shr(0, value) } function extract_from_storage_value_offset_uint256(slot_value) -> value @@ -201,7 +211,7 @@ object "C_25" { let expr := 0xffffffff let _1 := convert_rational_by_to_uint256(expr) update_transient_storage_value_offset_uint256_to_uint256(0x00, _1) - storage_set_to_zero_uint256(0x00, 0) + transient_storage_set_to_zero_uint256(0x00, 0) storage_set_to_zero_uint256(0x00, 0) let _2 := read_from_storage_split_offset_uint256(0x00) let expr_1 := _2 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol index f4badbc98845..dae46cd32b51 100644 --- a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol @@ -20,7 +20,6 @@ contract C is Base { // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // setAndClear() -> -// x() -> 1 +// x() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_2.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_delete_different_base_type.sol similarity index 75% rename from test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_2.sol rename to test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_delete_different_base_type.sol index f95b191c108c..d9a904f3caff 100644 --- a/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_2.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_delete_different_base_type.sol @@ -1,14 +1,12 @@ -pragma solidity >=0.0; - contract C { bool[3] flags = [true, true, true]; uint256 transient temp; - function f() external { + function setAndClear() external { temp = 0xffffffff; - assert(temp == 0xffffffff); delete flags; delete temp; + assert(temp == 0); } function getFlags() external returns(bool[3] memory) @@ -19,8 +17,7 @@ contract C { // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // getFlags() -> true, true, true -// f() -> +// setAndClear() -> // getFlags() -> false, false, false diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_pop_same_base_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_pop_same_base_type.sol new file mode 100644 index 000000000000..76dc10c43c11 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_pop_same_base_type.sol @@ -0,0 +1,30 @@ +contract C { + uint256[] arr; + uint256 transient t; + + function pushArr() external { + arr.push(1); + } + + function setAndClear() external { + t = 2; + delete t; + assert(t == 0); + arr.pop(); + } + + // Get value at index 0, which should have been cleared after arr.pop() + function getArr() external returns (uint256 value) { + assembly { + mstore(0, arr.slot) + value := sload(keccak256(0x00, 0x20)) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// pushArr() -> +// getArr() -> 1 +// setAndClear() -> +// getArr() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_2.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_delete_same_value_type.sol similarity index 63% rename from test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_2.sol rename to test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_delete_same_value_type.sol index 03e06747af1a..ad206c6eeee0 100644 --- a/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_2.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_delete_same_value_type.sol @@ -1,22 +1,18 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - contract C { uint256 transient varTransient; uint256 public varStorage = 0xeeeeeeeeee; - function foo() external { + function setAndClear() external { varTransient = 0xffffffff; - assert(varTransient == 0xffffffff); delete varStorage; delete varTransient; + assert(varTransient == 0); } } // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // varStorage() -> 0xeeeeeeeeee -// foo() -> +// setAndClear() -> // varStorage() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol index b1a38832158d..842cd47504b9 100644 --- a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol @@ -7,7 +7,7 @@ contract C { t = 2; delete m[0]; delete t; - assert(t == 2); + assert(t == 0); } function getM() external view returns (uint256) { @@ -17,7 +17,6 @@ contract C { // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // setAndClear() -> // getM() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol index 33a0dc2de46b..703816296268 100644 --- a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol @@ -4,16 +4,14 @@ contract C { address b; } - S s; + S s = S(1, address(0x1234)); uint256 transient t; function setAndDelete() external { - s.a = 1; - s.b = address(0x1234); t = 2; delete s; delete t; - assert(t == 2); + assert(t == 0); } function getS() external view returns (uint256, address) { @@ -22,7 +20,7 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- +// getS() -> 1, 4660 // setAndDelete() -> // getS() -> 0, 0 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol index 8e40422a9019..3af1b66e591c 100644 --- a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol @@ -20,7 +20,6 @@ contract C is Base { // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // setAndClear() -> -// x() -> 1 +// x() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_1.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_delete_different_base_type.sol similarity index 67% rename from test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_1.sol rename to test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_delete_different_base_type.sol index 4d84b23f70e7..c2e1c1a241cc 100644 --- a/test/libsolidity/semanticTests/storage/delete_storage_bool_array_transient_uint256_1.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_delete_different_base_type.sol @@ -1,13 +1,11 @@ -pragma solidity >=0.0; - contract C { bool[3] flags = [true, true, true]; uint256 transient temp; - function f() external { + function setAndClear() external { temp = 0xffffffff; - assert(temp == 0xffffffff); delete temp; + assert(temp == 0); delete flags; } @@ -19,8 +17,7 @@ contract C { // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // getFlags() -> true, true, true -// f() -> -// getFlags() -> true, true, true +// setAndClear() -> +// getFlags() -> false, false, false diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_partial_assignment_same_base_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_partial_assignment_same_base_type.sol new file mode 100644 index 000000000000..a9d3e0ae7384 --- /dev/null +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_partial_assignment_same_base_type.sol @@ -0,0 +1,27 @@ +contract C { + uint256[2] small; + uint256[4] large; + uint256 transient t; + + function setAndClear() external { + large = [1,2,3,4]; + small = [10, 20]; + t = 99; + + delete t; + assert(t == 0); + large = small; + } + + function getLarge() external view returns (uint256[4] memory) { + return large; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// setAndClear() -> +// gas irOptimized: 124683 +// gas legacy: 127807 +// gas legacyOptimized: 124828 +// getLarge() -> 10, 20, 0, 0 diff --git a/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_1.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_delete_same_value_type.sol similarity index 57% rename from test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_1.sol rename to test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_delete_same_value_type.sol index 08f8120be0ce..26e34fc26a55 100644 --- a/test/libsolidity/semanticTests/storage/delete_storage_u256_transient_u256_1.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_delete_same_value_type.sol @@ -1,22 +1,18 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - contract C { uint256 transient varTransient; uint256 public varStorage = 0xeeeeeeeeee; - function foo() external { + function setAndClear() external { varTransient = 0xffffffff; - assert(varTransient == 0xffffffff); delete varTransient; + assert(varTransient == 0); delete varStorage; } } // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // varStorage() -> 0xeeeeeeeeee -// foo() -> -// varStorage() -> 0xeeeeeeeeee +// setAndClear() -> +// varStorage() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol index 129fafad7507..6e262c8a6269 100644 --- a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol @@ -17,7 +17,6 @@ contract C { // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- // setAndClear() -> -// getM() -> 1 +// getM() -> 0 diff --git a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol index d499d0618374..c2127c9bad1f 100644 --- a/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol +++ b/test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol @@ -4,12 +4,10 @@ contract C { address b; } - S s; + S s = S(1, address(0x1234)); uint256 transient t; function setAndDelete() external { - s.a = 1; - s.b = address(0x1234); t = 2; delete t; assert(t == 0); @@ -22,7 +20,7 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: true // ---- +// getS() -> 1, 4660 // setAndDelete() -> -// getS() -> 1, 0 +// getS() -> 0, 0 From 74d96d4058c64dd4d7fc427ccf64895153815e89 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 22 Jun 2026 08:43:08 +0200 Subject: [PATCH 086/121] Move TarjanSCC from libyul to libsolutil (cherry picked from commit 0983a901d6683f6386a0702e115c29352c4ac056) --- libsolutil/CMakeLists.txt | 1 + libsolutil/TarjanSCC.h | 155 ++++++++++++++++++++++++++++++++++ test/CMakeLists.txt | 1 + test/libsolutil/TarjanSCC.cpp | 149 ++++++++++++++++++++++++++++++++ 4 files changed, 306 insertions(+) create mode 100644 libsolutil/TarjanSCC.h create mode 100644 test/libsolutil/TarjanSCC.cpp diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index 1ec12051a619..69c53cf9c086 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -35,6 +35,7 @@ set(sources StringUtils.h SwarmHash.cpp SwarmHash.h + TarjanSCC.h TemporaryDirectory.cpp TemporaryDirectory.h UTF8.cpp diff --git a/libsolutil/TarjanSCC.h b/libsolutil/TarjanSCC.h new file mode 100644 index 000000000000..a86dcb899c7d --- /dev/null +++ b/libsolutil/TarjanSCC.h @@ -0,0 +1,155 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace solidity::util +{ + +namespace detail +{ + +/// Callers must supply a dense `[0, N)` remapping; this struct conflates the node's +/// identity with its position in `adjacency` for performance. +template +struct TarjanSCC +{ + static constexpr std::size_t undefined = std::numeric_limits::max(); + + struct Frame + { + NodeIndex node; + std::size_t childIdx; + }; + + std::vector> const& adjacency; + /// numbers the nodes consecutively in the order in which they are discovered + std::vector discoveryIndex; + /// lowlink[v] corresponds to the smallest index of a node reachable through v's DFS subtree + std::vector lowlink; + std::vector onStack; + std::vector nodeStack; + std::vector workStack; + std::size_t nextIndex = 0; + std::vector> sccs; + + explicit TarjanSCC(std::vector> const& _adjacency): + adjacency(_adjacency), + discoveryIndex(_adjacency.size(), undefined), + lowlink(_adjacency.size(), 0), + onStack(_adjacency.size(), false) + {} + + void enter(NodeIndex const _v) + { + solAssert(_v < adjacency.size()); + discoveryIndex[_v] = nextIndex; + lowlink[_v] = nextIndex; + ++nextIndex; + nodeStack.push_back(_v); + onStack[_v] = true; + workStack.push_back({_v, 0}); + } + + void emitSCC(NodeIndex const _root) + { + solAssert(!nodeStack.empty()); + std::vector scc; + NodeIndex w; + do + { + w = nodeStack.back(); + nodeStack.pop_back(); + onStack[w] = false; + scc.push_back(w); + } + while (w != _root); + sccs.push_back(std::move(scc)); + } + + std::vector> run() && + { + for (NodeIndex root = 0; root < discoveryIndex.size(); ++root) + { + if (discoveryIndex[root] != undefined) + continue; + + // start new DFS tree + enter(root); + while (!workStack.empty()) + { + NodeIndex const v = workStack.back().node; + std::size_t const childIdx = workStack.back().childIdx; + if (childIdx < adjacency[v].size()) + { + // process next outgoing edge + NodeIndex const w = adjacency[v][childIdx]; + // advance v's currently handled edge before pushing w, so v resumes at the next child when w finishes + workStack.back().childIdx = childIdx + 1; + if (discoveryIndex[w] == undefined) + // Successor w has not yet been visited; recurse on it + enter(w); + else if (onStack[w]) + // Successor w is in stack S and hence in the current SCC + lowlink[v] = std::min(lowlink[v], discoveryIndex[w]); + } + else + { + // if v is a root node + if (lowlink[v] == discoveryIndex[v]) + // generate an SCC and pop the node stack + emitSCC(v); + + // pop v and propagate its lowlink to the parent (post-recursion update) + workStack.pop_back(); + if (!workStack.empty()) + { + NodeIndex const parent = workStack.back().node; + lowlink[parent] = std::min(lowlink[parent], lowlink[v]); + } + } + } + } + return std::move(sccs); + } +}; + +} + +/// Tarjan's strongly-connected-components algorithm. +/// Takes an adjacency list where `_adjacency[v]` is the list of successors of node `v`. Node IDs must lie in `[0, _adjacency.size())`. +/// Implementation based on the Wikipedia pseudocode. +/// +/// Wikipedia contributors, "Tarjan's strongly connected components algorithm," Wikipedia, The Free Encyclopedia, +/// https://en.wikipedia.org/w/index.php?title=Tarjan%27s_strongly_connected_components_algorithm&oldid=1341352351 +/// Tarjan, R.E., "Depth-First Search and Linear Graph Algorithms", https://doi.org/10.1137/0201010 +template +std::vector> computeStronglyConnectedComponents(std::vector> const& _adjacency) +{ + return detail::TarjanSCC(_adjacency).run(); +} + +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 211606363bc4..d8927dc5fccf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -43,6 +43,7 @@ set(libsolutil_sources libsolutil/LEB128.cpp libsolutil/StringUtils.cpp libsolutil/SwarmHash.cpp + libsolutil/TarjanSCC.cpp libsolutil/TemporaryDirectoryTest.cpp libsolutil/UTF8.cpp libsolutil/Whiskers.cpp diff --git a/test/libsolutil/TarjanSCC.cpp b/test/libsolutil/TarjanSCC.cpp new file mode 100644 index 000000000000..c6e8c350c711 --- /dev/null +++ b/test/libsolutil/TarjanSCC.cpp @@ -0,0 +1,149 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +/** + * Unit tests for the Tarjan SCC utility. + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace solidity::util::test +{ + +using NodeID = std::uint32_t; +using Graph = std::vector>; +using SCCList = std::vector>; + +namespace +{ + +namespace bdata = boost::unit_test::data; + +SCCList compute(Graph const& _g) +{ + return solidity::util::computeStronglyConnectedComponents(_g); +} + +SCCList canonicalize(SCCList _sccs) +{ + for (auto& scc: _sccs) + ranges::sort(scc); + ranges::sort(_sccs); + return _sccs; +} + +std::string formatSCCs(SCCList const& _sccs) +{ + auto const formatScc = [](std::vector const& _scc) { + return fmt::format("{{{}}}", fmt::join(_scc, ", ")); + }; + return fmt::format("{{{}}}", fmt::join(_sccs | ranges::views::transform(formatScc), ", ")); +} + +boost::test_tools::predicate_result sccsEqual(SCCList const& _actual, SCCList const& _expected) +{ + SCCList const canonicalActual = canonicalize(_actual); + SCCList const canonicalExpected = canonicalize(_expected); + if (canonicalActual == canonicalExpected) + return true; + boost::test_tools::predicate_result result(false); + result.message() + << "SCC partitions differ (compared as sets of sets).\n" + << " actual: " << formatSCCs(canonicalActual) << "\n" + << " expected: " << formatSCCs(canonicalExpected); + return result; +} + +struct PartitionCase +{ + std::string name; + Graph graph; + SCCList expectedSCCs; +}; + +std::ostream& operator<<(std::ostream& _os, PartitionCase const& _case) +{ + return _os << _case.name; +} + +std::vector const partitionCases = { + {"empty_graph", {}, {}}, + {"single_node_no_edges", Graph(1), {{0}}}, + {"single_node_self_loop", {{0}}, {{0}}}, + {"two_cycle", {{1}, {0}}, {{0, 1}}}, + {"three_cycle", {{1}, {2}, {0}}, {{0, 1, 2}}}, + {"linear_chain", {{1}, {2}, {3}, {}}, {{0}, {1}, {2}, {3}}}, + // 0 <-> 1, plus self-loop on 0. Yields one SCC {0, 1}. + {"self_loop_inside_two_cycle", {{0, 1}, {0}}, {{0, 1}}}, + // 0 -> 2, 1 -> 2: three singleton SCCs. + {"dag_with_shared_successor", {{2}, {2}, {}}, {{0}, {1}, {2}}}, + { + "clrs_example", + // CLRS, 3rd ed., Fig. 22.9 (relabeled a..h -> 0..7). + // 0 -> 1 + // 1 -> 2, 4, 5 + // 2 -> 3, 6 + // 3 -> 2, 7 + // 4 -> 0, 5 + // 5 -> 6 + // 6 -> 5, 7 + // 7 -> 7 + {{1}, {2, 4, 5}, {3, 6}, {2, 7}, {0, 5}, {6}, {5, 7}, {7}}, + {{0, 1, 4}, {2, 3}, {5, 6}, {7}}, + }, + { + "multiple_disjoint_components", + // Four components: 0 <-> 1, 2 <-> 3, 4 -> 5. + {{1}, {0}, {3}, {2}, {5}, {}}, + {{0, 1}, {2, 3}, {4}, {5}}, + }, + { + "nested_sccs_with_cross_edges", + // Two SCCs connected by an inter-SCC edge: 0 <-> 1 (A), 2 <-> 3 (B), 1 -> 2. + {{1}, {0, 2}, {3}, {2}}, + {{0, 1}, {2, 3}}, + }, + // 0 -> 1, node 2 isolated: 2 still emitted as its own SCC. + {"unreachable_node_still_emitted", {{1}, {}, {}}, {{0}, {1}, {2}}}, +}; + +} + +BOOST_AUTO_TEST_SUITE(TarjanSCC) + +BOOST_DATA_TEST_CASE(partition, bdata::make(partitionCases), testCase) +{ + BOOST_CHECK(sccsEqual(compute(testCase.graph), testCase.expectedSCCs)); +} + +BOOST_AUTO_TEST_SUITE_END() + +} From b5f59ce4da4ee1504539a620a705aa331e2d870b Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:27:00 +0200 Subject: [PATCH 087/121] Add Yul AST call graph recursion tests (cherry picked from commit a0a3dd8f2368f9a0412d625772eb0ac1046979fb) --- test/CMakeLists.txt | 2 + test/InteractiveTests.h | 2 + test/libyul/CallGraphTest.cpp | 111 ++++++++++++++++++ test/libyul/CallGraphTest.h | 36 ++++++ .../intersecting_recursive_cycles.yul | 16 +++ test/libyul/yulCallGraph/ambiguous_names.yul | 6 + .../yulCallGraph/ambiguous_names_nested.yul | 12 ++ .../branching_into_and_out_of_scc.yul | 13 ++ test/libyul/yulCallGraph/caller_into_scc.yul | 10 ++ .../yulCallGraph/direct_plus_mutual.yul | 10 ++ test/libyul/yulCallGraph/direct_self_call.yul | 6 + .../libyul/yulCallGraph/duplicate_callees.yul | 11 ++ .../yulCallGraph/intersecting_cycles.yul | 12 ++ .../intersecting_cycles_visitation_order.yul | 12 ++ test/libyul/yulCallGraph/leaf.yul | 6 + test/libyul/yulCallGraph/mixed.yul | 10 ++ .../yulCallGraph/multi_callee_three_scc.yul | 13 ++ .../multiple_distinct_callees.yul | 13 ++ .../yulCallGraph/mutual_three_cycle.yul | 10 ++ test/libyul/yulCallGraph/mutual_two_cycle.yul | 8 ++ test/libyul/yulCallGraph/nested_functions.yul | 16 +++ .../yulCallGraph/non_recursive_chain.yul | 10 ++ test/libyul/yulCallGraph/self_and_other.yul | 11 ++ test/libyul/yulCallGraph/shared_callee.yul | 10 ++ test/tools/CMakeLists.txt | 1 + 25 files changed, 367 insertions(+) create mode 100644 test/libyul/CallGraphTest.cpp create mode 100644 test/libyul/CallGraphTest.h create mode 100644 test/libyul/functionSideEffects/intersecting_recursive_cycles.yul create mode 100644 test/libyul/yulCallGraph/ambiguous_names.yul create mode 100644 test/libyul/yulCallGraph/ambiguous_names_nested.yul create mode 100644 test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul create mode 100644 test/libyul/yulCallGraph/caller_into_scc.yul create mode 100644 test/libyul/yulCallGraph/direct_plus_mutual.yul create mode 100644 test/libyul/yulCallGraph/direct_self_call.yul create mode 100644 test/libyul/yulCallGraph/duplicate_callees.yul create mode 100644 test/libyul/yulCallGraph/intersecting_cycles.yul create mode 100644 test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul create mode 100644 test/libyul/yulCallGraph/leaf.yul create mode 100644 test/libyul/yulCallGraph/mixed.yul create mode 100644 test/libyul/yulCallGraph/multi_callee_three_scc.yul create mode 100644 test/libyul/yulCallGraph/multiple_distinct_callees.yul create mode 100644 test/libyul/yulCallGraph/mutual_three_cycle.yul create mode 100644 test/libyul/yulCallGraph/mutual_two_cycle.yul create mode 100644 test/libyul/yulCallGraph/nested_functions.yul create mode 100644 test/libyul/yulCallGraph/non_recursive_chain.yul create mode 100644 test/libyul/yulCallGraph/self_and_other.yul create mode 100644 test/libyul/yulCallGraph/shared_callee.yul diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d8927dc5fccf..dbbcf3eaec81 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -144,6 +144,8 @@ detect_stray_source_files("${libsolidity_util_sources}" "libsolidity/util/") set(libyul_sources libyul/Common.cpp libyul/Common.h + libyul/CallGraphTest.cpp + libyul/CallGraphTest.h libyul/CompilabilityChecker.cpp libyul/ControlFlowGraphTest.cpp libyul/ControlFlowGraphTest.h diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index 107a6aae0bef..d53406ef693b 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,7 @@ Testsuite const g_interactiveTestsuites[] = { {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, {"Yul Control Flow Graph", "libyul", "yulControlFlowGraph", false, false, &yul::test::ControlFlowGraphTest::create}, {"Yul SSA Control Flow Graph", "libyul", "yulSSAControlFlowGraph", false, false, &yul::test::SSAControlFlowGraphTest::create}, + {"Yul Call Graph", "libyul", "yulCallGraph", false, false, &yul::test::CallGraphTest::create}, {"Yul Stack Layout", "libyul", "yulStackLayout", false, false, &yul::test::StackLayoutGeneratorTest::create}, {"Yul Stack Shuffling", "libyul", "yulStackShuffling", false, false, &yul::test::StackShufflingTest::create}, {"Control Flow Side Effects", "libyul", "controlFlowSideEffects", false, false, &yul::test::ControlFlowSideEffectsTest::create}, diff --git a/test/libyul/CallGraphTest.cpp b/test/libyul/CallGraphTest.cpp new file mode 100644 index 000000000000..5fad64777b44 --- /dev/null +++ b/test/libyul/CallGraphTest.cpp @@ -0,0 +1,111 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +using namespace solidity; +using namespace solidity::langutil; +using namespace solidity::yul; +using namespace solidity::yul::test; +using namespace solidity::frontend; +using namespace solidity::frontend::test; + +namespace +{ + +/// Collects function names in the order in which the functions are defined, descending into nested +/// functions, so that the call graph can be printed deterministically. +struct FunctionNameCollector: ASTWalker +{ + using ASTWalker::operator(); + void operator()(FunctionDefinition const& _function) override + { + names.emplace_back(_function.name); + ASTWalker::operator()(_function); + } + + std::vector names; +}; + +} + +std::unique_ptr CallGraphTest::create(Config const& _config) +{ + return std::make_unique(_config.filename); +} + +CallGraphTest::CallGraphTest(std::string const& _filename): + TestCase(_filename) +{ + m_source = m_reader.source(); + m_expectation = m_reader.simpleExpectations(); +} + +TestCase::TestResult CallGraphTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) +{ + YulStack const yulStack = parseYul(m_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + + if (yulStack.hasErrors()) + { + printYulErrors(yulStack, _stream, _linePrefix, _formatted); + return TestResult::FatalError; + } + + Block const& root = yulStack.parserResult()->code()->root(); + + std::ostringstream out; + try + { + CallGraph const callGraph = CallGraphGenerator::callGraph(root); + std::set const recursive = callGraph.recursiveFunctions(); + + auto classification = [&](FunctionHandle const& _function) { + return recursive.contains(_function) ? "recursive" : "non-recursive"; + }; + + FunctionNameCollector collector; + collector(root); + + // The outermost (non-function) context is denoted by the empty name in the call graph. + out << "
: " << classification(YulName{}) << "\n"; + for (YulName const& name: collector.names) + out << name.str() << ": " << classification(name) << "\n"; + } + catch (langutil::InternalCompilerError const& _error) + { + out << "InternalCompilerError: " << (_error.comment() ? *_error.comment() : "") << "\n"; + } + m_obtainedResult = out.str(); + + return checkResult(_stream, _linePrefix, _formatted); +} diff --git a/test/libyul/CallGraphTest.h b/test/libyul/CallGraphTest.h new file mode 100644 index 000000000000..0b644cb2e1b9 --- /dev/null +++ b/test/libyul/CallGraphTest.h @@ -0,0 +1,36 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include + +namespace solidity::yul::test +{ + +class CallGraphTest: public frontend::test::TestCase +{ +public: + static std::unique_ptr create(Config const& _config); + explicit CallGraphTest(std::string const& _filename); + TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; +}; + +} diff --git a/test/libyul/functionSideEffects/intersecting_recursive_cycles.yul b/test/libyul/functionSideEffects/intersecting_recursive_cycles.yul new file mode 100644 index 000000000000..de238885a5d6 --- /dev/null +++ b/test/libyul/functionSideEffects/intersecting_recursive_cycles.yul @@ -0,0 +1,16 @@ +{ + // Two recursive cycles sharing alpha: alpha <-> beta and alpha -> gamma -> beta -> alpha, + // so {alpha, beta, gamma} is a single strongly-connected component (all three are recursive). + // + // The old call-graph cycle finder mis-classified gamma as non-recursive (SOL-2026-2), but the + // side-effect result is unaffected: gamma still calls into the (correctly detected) alpha/beta + // cycle, so "can loop" is propagated to it along the call edges regardless of the recursion flag. + function alpha() { beta() gamma() } + function beta() { alpha() } + function gamma() { beta() } +} +// ---- +// : movable, movable apart from effects, can be removed, can be removed if no msize +// alpha: movable apart from effects, can loop +// beta: movable apart from effects, can loop +// gamma: movable apart from effects, can loop diff --git a/test/libyul/yulCallGraph/ambiguous_names.yul b/test/libyul/yulCallGraph/ambiguous_names.yul new file mode 100644 index 000000000000..f8cf3924360e --- /dev/null +++ b/test/libyul/yulCallGraph/ambiguous_names.yul @@ -0,0 +1,6 @@ +{ + { function f() {} } + { function f() {} } +} +// ---- +// InternalCompilerError: CallGraphGenerator requires a disambiguated AST: duplicate function name f. diff --git a/test/libyul/yulCallGraph/ambiguous_names_nested.yul b/test/libyul/yulCallGraph/ambiguous_names_nested.yul new file mode 100644 index 000000000000..4cc98c7e1097 --- /dev/null +++ b/test/libyul/yulCallGraph/ambiguous_names_nested.yul @@ -0,0 +1,12 @@ +{ + { + function f() { + function g() {} + } + } + { + function g() {} + } +} +// ---- +// InternalCompilerError: CallGraphGenerator requires a disambiguated AST: duplicate function name g. diff --git a/test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul b/test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul new file mode 100644 index 000000000000..82eccf25b6f4 --- /dev/null +++ b/test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul @@ -0,0 +1,13 @@ +{ + function f() { + g() + h() + } + function g() { f() } + function h() {} +} +// ---- +//
: non-recursive +// f: recursive +// g: recursive +// h: non-recursive diff --git a/test/libyul/yulCallGraph/caller_into_scc.yul b/test/libyul/yulCallGraph/caller_into_scc.yul new file mode 100644 index 000000000000..4167f3caf651 --- /dev/null +++ b/test/libyul/yulCallGraph/caller_into_scc.yul @@ -0,0 +1,10 @@ +{ + function f() { g() } + function g() { h() } + function h() { g() } +} +// ---- +//
: non-recursive +// f: non-recursive +// g: recursive +// h: recursive diff --git a/test/libyul/yulCallGraph/direct_plus_mutual.yul b/test/libyul/yulCallGraph/direct_plus_mutual.yul new file mode 100644 index 000000000000..f75690c6ba32 --- /dev/null +++ b/test/libyul/yulCallGraph/direct_plus_mutual.yul @@ -0,0 +1,10 @@ +{ + function f() { f() } + function g() { h() } + function h() { g() } +} +// ---- +//
: non-recursive +// f: recursive +// g: recursive +// h: recursive diff --git a/test/libyul/yulCallGraph/direct_self_call.yul b/test/libyul/yulCallGraph/direct_self_call.yul new file mode 100644 index 000000000000..7a57413da61b --- /dev/null +++ b/test/libyul/yulCallGraph/direct_self_call.yul @@ -0,0 +1,6 @@ +{ + function f() { f() } +} +// ---- +//
: non-recursive +// f: recursive diff --git a/test/libyul/yulCallGraph/duplicate_callees.yul b/test/libyul/yulCallGraph/duplicate_callees.yul new file mode 100644 index 000000000000..549ca59daa05 --- /dev/null +++ b/test/libyul/yulCallGraph/duplicate_callees.yul @@ -0,0 +1,11 @@ +{ + function f() { + g() + g() + } + function g() {} +} +// ---- +//
: non-recursive +// f: non-recursive +// g: non-recursive diff --git a/test/libyul/yulCallGraph/intersecting_cycles.yul b/test/libyul/yulCallGraph/intersecting_cycles.yul new file mode 100644 index 000000000000..b38a35720136 --- /dev/null +++ b/test/libyul/yulCallGraph/intersecting_cycles.yul @@ -0,0 +1,12 @@ +{ + // Two recursive cycles sharing alpha: alpha <-> beta and alpha -> gamma -> beta -> alpha, + // so {alpha, beta, gamma} is a single strongly-connected component and all three are recursive. + function alpha() { beta() gamma() } + function beta() { alpha() } + function gamma() { beta() } +} +// ---- +//
: non-recursive +// alpha: recursive +// beta: recursive +// gamma: non-recursive diff --git a/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul b/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul new file mode 100644 index 000000000000..1e54d1c51953 --- /dev/null +++ b/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul @@ -0,0 +1,12 @@ +{ + // Same topology as intersecting_cycles.yul (two recursive cycles sharing a node, so the whole + // {hub, spoke, rim} set is a single strongly-connected component) but with different function names. + function hub() { spoke() rim() } + function spoke() { hub() } + function rim() { spoke() } +} +// ---- +//
: non-recursive +// hub: recursive +// spoke: recursive +// rim: recursive diff --git a/test/libyul/yulCallGraph/leaf.yul b/test/libyul/yulCallGraph/leaf.yul new file mode 100644 index 000000000000..b44705017a74 --- /dev/null +++ b/test/libyul/yulCallGraph/leaf.yul @@ -0,0 +1,6 @@ +{ + function f() {} +} +// ---- +//
: non-recursive +// f: non-recursive diff --git a/test/libyul/yulCallGraph/mixed.yul b/test/libyul/yulCallGraph/mixed.yul new file mode 100644 index 000000000000..e1bd7247fa38 --- /dev/null +++ b/test/libyul/yulCallGraph/mixed.yul @@ -0,0 +1,10 @@ +{ + function f() { g() } + function g() { f() } + function h() {} +} +// ---- +//
: non-recursive +// f: recursive +// g: recursive +// h: non-recursive diff --git a/test/libyul/yulCallGraph/multi_callee_three_scc.yul b/test/libyul/yulCallGraph/multi_callee_three_scc.yul new file mode 100644 index 000000000000..dd1396a6e314 --- /dev/null +++ b/test/libyul/yulCallGraph/multi_callee_three_scc.yul @@ -0,0 +1,13 @@ +{ + function a() { + b() + c() + } + function b() { a() } + function c() { b() } +} +// ---- +//
: non-recursive +// a: recursive +// b: recursive +// c: recursive diff --git a/test/libyul/yulCallGraph/multiple_distinct_callees.yul b/test/libyul/yulCallGraph/multiple_distinct_callees.yul new file mode 100644 index 000000000000..e67e01ca98f4 --- /dev/null +++ b/test/libyul/yulCallGraph/multiple_distinct_callees.yul @@ -0,0 +1,13 @@ +{ + function f() { + g() + h() + } + function g() {} + function h() {} +} +// ---- +//
: non-recursive +// f: non-recursive +// g: non-recursive +// h: non-recursive diff --git a/test/libyul/yulCallGraph/mutual_three_cycle.yul b/test/libyul/yulCallGraph/mutual_three_cycle.yul new file mode 100644 index 000000000000..1cdeb220de2b --- /dev/null +++ b/test/libyul/yulCallGraph/mutual_three_cycle.yul @@ -0,0 +1,10 @@ +{ + function f() { g() } + function g() { h() } + function h() { f() } +} +// ---- +//
: non-recursive +// f: recursive +// g: recursive +// h: recursive diff --git a/test/libyul/yulCallGraph/mutual_two_cycle.yul b/test/libyul/yulCallGraph/mutual_two_cycle.yul new file mode 100644 index 000000000000..123e266982cf --- /dev/null +++ b/test/libyul/yulCallGraph/mutual_two_cycle.yul @@ -0,0 +1,8 @@ +{ + function f() { g() } + function g() { f() } +} +// ---- +//
: non-recursive +// f: recursive +// g: recursive diff --git a/test/libyul/yulCallGraph/nested_functions.yul b/test/libyul/yulCallGraph/nested_functions.yul new file mode 100644 index 000000000000..8bd506003842 --- /dev/null +++ b/test/libyul/yulCallGraph/nested_functions.yul @@ -0,0 +1,16 @@ +{ + // Nested function definitions with a cycle a -> b -> c -> a. + function a() { + function b() { + function c() { a() } + c() + } + b() + } + a() +} +// ---- +//
: non-recursive +// a: recursive +// b: recursive +// c: recursive diff --git a/test/libyul/yulCallGraph/non_recursive_chain.yul b/test/libyul/yulCallGraph/non_recursive_chain.yul new file mode 100644 index 000000000000..20086c873c71 --- /dev/null +++ b/test/libyul/yulCallGraph/non_recursive_chain.yul @@ -0,0 +1,10 @@ +{ + function f() { g() } + function g() { h() } + function h() {} +} +// ---- +//
: non-recursive +// f: non-recursive +// g: non-recursive +// h: non-recursive diff --git a/test/libyul/yulCallGraph/self_and_other.yul b/test/libyul/yulCallGraph/self_and_other.yul new file mode 100644 index 000000000000..be843421f297 --- /dev/null +++ b/test/libyul/yulCallGraph/self_and_other.yul @@ -0,0 +1,11 @@ +{ + function f() { + f() + g() + } + function g() {} +} +// ---- +//
: non-recursive +// f: recursive +// g: non-recursive diff --git a/test/libyul/yulCallGraph/shared_callee.yul b/test/libyul/yulCallGraph/shared_callee.yul new file mode 100644 index 000000000000..4b28e34f2b49 --- /dev/null +++ b/test/libyul/yulCallGraph/shared_callee.yul @@ -0,0 +1,10 @@ +{ + function f() { h() } + function g() { h() } + function h() {} +} +// ---- +//
: non-recursive +// f: non-recursive +// g: non-recursive +// h: non-recursive diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 289f2f2def35..84eb69013418 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable(isoltest ../libsolidity/ASTPropertyTest.cpp ../libsolidity/FunctionDependencyGraphTest.cpp ../libsolidity/SMTCheckerTest.cpp + ../libyul/CallGraphTest.cpp ../libyul/Common.cpp ../libyul/ControlFlowGraphTest.cpp ../libyul/SSAControlFlowGraphTest.cpp From c16578df1e7963366ed158f5d05a6fedc3b4e31b Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Sat, 20 Jun 2026 18:42:20 +0200 Subject: [PATCH 088/121] Add tests reproducing spurious memory spilling (cherry picked from commit 139d696bc9aa3d59d295256d128c29602dd1d18c) --- .../in.sol | 65 +++++++++++ .../input.json | 12 ++ .../output.json | 36 ++++++ .../intersecting_recursive_cycles.yul | 3 +- .../stackLimitEvader/intersecting_cycles.yul | 105 ++++++++++++++++++ 5 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/in.sol create mode 100644 test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json create mode 100644 test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json create mode 100644 test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/in.sol b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/in.sol new file mode 100644 index 000000000000..3e2f0619cf8e --- /dev/null +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/in.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity *; + +// Regression test for stack-to-memory spilling miscompilation SOL-2026-2 caused by the call graph cycle detection +// misclassifying functions in intersecting recursive cycles. +// +// Call graph: a -> {b, c}, b -> a, c -> b +// so {a, b, c} is a single strongly-connected component and all three functions are recursive, spilling is unsound. +// The stack limit evader must refuse to spill here. +contract C { + uint256[26] public seed; + + function trigger() external returns (uint256 storedAt3) { + a(3); + storedAt3 = seed[3]; + } + + function a(uint256 m) internal { + if (m == 0) return; + b(m); + c(m); + } + function b(uint256 m) internal { + if (m == 0) return; + a(m - 1); + } + function c(uint256 m) internal { + if (m == 0) return; + uint256 v1 = seed[0] ^ m; + uint256 v2 = seed[1] ^ m; + uint256 v3 = seed[2] ^ m; + uint256 v4 = seed[3] ^ m; + uint256 v5 = seed[4] ^ m; + uint256 v6 = seed[5] ^ m; + uint256 v7 = seed[6] ^ m; + uint256 v8 = seed[7] ^ m; + uint256 v9 = seed[8] ^ m; + uint256 v10 = seed[9] ^ m; + uint256 v11 = seed[10] ^ m; + uint256 v12 = seed[11] ^ m; + uint256 v13 = seed[12] ^ m; + uint256 v14 = seed[13] ^ m; + uint256 v15 = seed[14] ^ m; + uint256 v16 = seed[15] ^ m; + uint256 v17 = seed[16] ^ m; + uint256 v18 = seed[17] ^ m; + uint256 v19 = seed[18] ^ m; + uint256 v20 = seed[19] ^ m; + uint256 v21 = seed[20] ^ m; + uint256 v22 = seed[21] ^ m; + uint256 v23 = seed[22] ^ m; + uint256 v24 = seed[23] ^ m; + uint256 v25 = seed[24] ^ m; + + b(m - 1); + + // Read m back, provoking a stack too deep situation + seed[m] = m; + // Keep v1..v25 alive across the b(m - 1) call + seed[25] = + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 + + v11 + v12 + v13 + v14 + v15 + v16 + v17 + v18 + v19 + v20 + + v21 + v22 + v23 + v24 + v25; + } +} diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json new file mode 100644 index 000000000000..dc86ac68494e --- /dev/null +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "in.sol": {"urls": ["in.sol"]} + }, + "settings": { + "viaIR": true, + "outputSelection": { + "*": {"*": ["evm.bytecode"]} + } + } +} diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json new file mode 100644 index 000000000000..d722677373f0 --- /dev/null +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json @@ -0,0 +1,36 @@ +{ + "contracts": { + "in.sol": { + "C": { + "evm": { + "bytecode": { + "functionDebugData": { + "allocate_unbounded": { + "entryPoint": 32, + "id": null, + "parameterSlots": 0, + "returnSlots": 1 + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "entryPoint": 38, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + } + }, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes":"", + "sourceMap": "567:1327:0:-:0;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;" + } + } + } + } + }, + "sources": { + "in.sol": { + "id": 0 + } + } +} diff --git a/test/libyul/functionSideEffects/intersecting_recursive_cycles.yul b/test/libyul/functionSideEffects/intersecting_recursive_cycles.yul index de238885a5d6..9cda724b46e7 100644 --- a/test/libyul/functionSideEffects/intersecting_recursive_cycles.yul +++ b/test/libyul/functionSideEffects/intersecting_recursive_cycles.yul @@ -3,8 +3,7 @@ // so {alpha, beta, gamma} is a single strongly-connected component (all three are recursive). // // The old call-graph cycle finder mis-classified gamma as non-recursive (SOL-2026-2), but the - // side-effect result is unaffected: gamma still calls into the (correctly detected) alpha/beta - // cycle, so "can loop" is propagated to it along the call edges regardless of the recursion flag. + // side-effect result is unaffected. function alpha() { beta() gamma() } function beta() { alpha() } function gamma() { beta() } diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul new file mode 100644 index 000000000000..cfa226a4e50f --- /dev/null +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul @@ -0,0 +1,105 @@ +{ + mstore(0x40, memoryguard(128)) + ba() + function ba() { + z() + y() + } + function z() { + ba() + } + function y() { + let a1 := calldataload(mul(1,4)) + let a2 := calldataload(mul(2,4)) + let a3 := calldataload(mul(3,4)) + let a4 := calldataload(mul(4,4)) + let a5 := calldataload(mul(5,4)) + let a6 := calldataload(mul(6,4)) + let a7 := calldataload(mul(7,4)) + let a8 := calldataload(mul(8,4)) + let a9 := calldataload(mul(9,4)) + a1 := calldataload(mul(0,4)) + let a10 := calldataload(mul(10,4)) + let a11 := calldataload(mul(11,4)) + let a12 := calldataload(mul(12,4)) + let a13 := calldataload(mul(13,4)) + let a14 := calldataload(mul(14,4)) + let a15 := calldataload(mul(15,4)) + let a16 := calldataload(mul(16,4)) + let a17 := calldataload(mul(17,4)) + z() + sstore(0, a1) + sstore(mul(17,4), a17) + sstore(mul(16,4), a16) + sstore(mul(15,4), a15) + sstore(mul(14,4), a14) + sstore(mul(13,4), a13) + sstore(mul(12,4), a12) + sstore(mul(11,4), a11) + sstore(mul(10,4), a10) + sstore(mul(9,4), a9) + sstore(mul(8,4), a8) + sstore(mul(7,4), a7) + sstore(mul(6,4), a6) + sstore(mul(5,4), a5) + sstore(mul(4,4), a4) + sstore(mul(3,4), a3) + sstore(mul(2,4), a2) + sstore(mul(1,4), a1) + } +} +// ==== +// ---- +// step: stackLimitEvader +// +// { +// mstore(0x40, memoryguard(0xa0)) +// ba() +// function ba() +// { +// z() +// y() +// } +// function z() +// { ba() } +// function y() +// { +// mstore(0x80, calldataload(mul(1, 4))) +// let a2 := calldataload(mul(2, 4)) +// let a3 := calldataload(mul(3, 4)) +// let a4 := calldataload(mul(4, 4)) +// let a5 := calldataload(mul(5, 4)) +// let a6 := calldataload(mul(6, 4)) +// let a7 := calldataload(mul(7, 4)) +// let a8 := calldataload(mul(8, 4)) +// let a9 := calldataload(mul(9, 4)) +// mstore(0x80, calldataload(mul(0, 4))) +// let a10 := calldataload(mul(10, 4)) +// let a11 := calldataload(mul(11, 4)) +// let a12 := calldataload(mul(12, 4)) +// let a13 := calldataload(mul(13, 4)) +// let a14 := calldataload(mul(14, 4)) +// let a15 := calldataload(mul(15, 4)) +// let a16 := calldataload(mul(16, 4)) +// let a17 := calldataload(mul(17, 4)) +// z() +// sstore(0, mload(0x80)) +// sstore(mul(17, 4), a17) +// sstore(mul(16, 4), a16) +// sstore(mul(15, 4), a15) +// sstore(mul(14, 4), a14) +// sstore(mul(13, 4), a13) +// sstore(mul(12, 4), a12) +// sstore(mul(11, 4), a11) +// sstore(mul(10, 4), a10) +// sstore(mul(9, 4), a9) +// sstore(mul(8, 4), a8) +// sstore(mul(7, 4), a7) +// sstore(mul(6, 4), a6) +// sstore(mul(5, 4), a5) +// sstore(mul(4, 4), a4) +// sstore(mul(3, 4), a3) +// sstore(mul(2, 4), a2) +// sstore(mul(1, 4), mload(0x80)) +// } +// } From 9b997d0918a1baf9b7d86816badf1c147dd07da8 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Sat, 20 Jun 2026 18:44:25 +0200 Subject: [PATCH 089/121] Fix call graph cycle detection for intersecting recursive cycles Use Tarjan's strongly-connected-components algorithm: a function is recursive iff it lies in a non-trivial SCC or has a self-edge. Also add intersection recursive cycles regression test to function specializer tests. (cherry picked from commit 502561897c59e31f5c5cb1218874b01750e6aa2d) --- docs/bugs.json | 47 +++- docs/bugs_by_version.json | 213 +++++++++++++++++- libyul/optimiser/CallGraphGenerator.cpp | 105 ++++++--- .../output.json | 49 ++-- .../yulCallGraph/intersecting_cycles.yul | 2 +- .../intersecting_cycles_visitation_order.yul | 8 +- .../intersecting_recursive_cycles.yul | 35 +++ .../stackLimitEvader/intersecting_cycles.yul | 10 +- 8 files changed, 388 insertions(+), 81 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/functionSpecializer/intersecting_recursive_cycles.yul diff --git a/docs/bugs.json b/docs/bugs.json index 4b5dd74f8571..4710520cbee9 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,41 @@ [ + { + "uid": "SOL-2026-2", + "name": "UnsoundSpillInMutualRecursion", + "summary": "Local variables of a function involved in mutual recursion may spuriously be moved to fixed memory offsets and overwritten across recursive calls.", + "description": "To work around the 16-slot stack access limit of the EVM, the IR-based code generator can move local variables of stack-too-deep functions to fixed memory offsets. This relocation is unsound for recursive functions: a fixed offset would be shared by all activations of the function, so a recursive call would overwrite the caller's value. The stack limit evader therefore must not relocate variables of functions that are part of a recursive call chain. To this end, the call graph was searched for cycles using a path-based depth-first search that, once a function had been fully explored and popped from the search path, short-circuited on it on any later visit. As a result, a function shared between several intersecting cycles could be reached first through a path that did not yet close a cycle through it, get marked as finished, and then be skipped when a later path would have revealed that it does lie on a cycle. Such a function was misclassified as non-recursive. When a misclassified function was complex enough for the stack limit evader to relocate some of its variables, those variables were moved to fixed memory offsets and silently corrupted on recursion, producing wrong results rather than a compile-time error. Triggering the bug requires the IR pipeline, a set of mutually recursive functions whose call graph contains intersecting cycles, at least one of the functions in an undetected part of a cycle being complex enough to require relocation to memory, and an unfortunate processing order of the functions (which depends on the hashes of their Yul names). It is independent of whether the optimizer is enabled.", + "link": "https://blog.soliditylang.org/2026/07/08/unsound-spill-in-mutual-recursion-bug/", + "introduced": "0.7.2", + "fixed": "0.8.36", + "severity": "medium", + "conditions": { + "viaIR": true + } + }, + { + "uid": "SOL-2026-1", + "name": "TransientStorageClearingHelperCollision", + "summary": "Clearing both storage and transient storage variables in the same contract may result in only one of these locations being cleared.", + "description": "The IR-based code generator provides a set of Yul helper functions for basic operations, such as clearing, copying, encoding or type conversions. Not all functions are used by every contract. The codegen appends them to the generated sources individually, only when an operation that would invoke one of them is encountered. Utility functions are often specialized for different types and locations. Since Yul does not support generic functions, specialization is done by generating multiple versions of the same function, with the information distinguishing the variants embedded in their names. However, if not all the necessary bits of distinguishing information are properly accounted for, two helpers may end up with the same name, causing a collision. In this situation the codegen includes only one of them, with calls to both variants invoking it. This happened with the ``set_to_zero`` helper used when an area of transient or persistent storage needs to be cleared. The helper name was missing the location information, which resulted in a collision between the persistent and transient storage variants for the same type. This meant that contracts clearing both locations would actually clear only one, leaving the other untouched. Which location ended up being cleared depended on the order in which the code generator processed the input. The necessary condition to trigger the bug was the use of ``delete`` operator on a transient storage variable. This was due to value types being the only types supported in transient storage and ``delete`` being the only operation invoking the helper allowed on such types. The other necessary condition was clearing of persistent storage and in this case the range of affected operations was wider: operator ``delete``, array ``pop()`` or assignment that resulted in a longer array being overwritten with a shorter one. The cleared variable itself also did not necessarily have to be of the same type. It was enough that a matching value type was nested in it. It also did not always have to be the exact same value type - clearing operations on reference types are usually performed at slot granularity, treating every slot as ``uint256`` rather than clearing every value packed into it individually. To trigger the bug both operations had to be present within the same piece of bytecode. Independent contracts, not related through inheritance, would not affect each other this way. The presence of one operation only in creation code and the other only in deployed code would not trigger the bug either.", + "link": "https://blog.soliditylang.org/2026/02/18/transient-storage-clearing-helper-collision-bug/", + "introduced": "0.8.28", + "fixed": "0.8.34", + "severity": "high", + "conditions": { + "viaIR": true, + "evmVersion": ">=cancun" + } + }, + { + "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", @@ -476,7 +513,7 @@ "uid": "SOL-2017-5", "name": "ZeroFunctionSelector", "summary": "It is possible to craft the name of a function such that it is executed instead of the fallback function in very specific circumstances.", - "description": "If a function has a selector consisting only of zeros, is payable and part of a contract that does not have a fallback function and at most five external functions in total, this function is called instead of the fallback function if Trx is sent to the contract without data.", + "description": "If a function has a selector consisting only of zeros, is payable and part of a contract that does not have a fallback function and at most five external functions in total, this function is called instead of the fallback function if Ether is sent to the contract without data.", "fixed": "0.4.18", "severity": "very low" }, @@ -561,8 +598,8 @@ { "uid": "SOL-2016-7", "name": "LibrariesNotCallableFromPayableFunctions", - "summary": "Library functions threw an exception when called from a call that received Trx.", - "description": "Library functions are protected against sending them Trx through a call. Since the DELEGATECALL opcode forwards the information about how much Trx was sent with a call, the library function incorrectly assumed that Trx was sent to the library and threw an exception.", + "summary": "Library functions threw an exception when called from a call that received Ether.", + "description": "Library functions are protected against sending them Ether through a call. Since the DELEGATECALL opcode forwards the information about how much Ether was sent with a call, the library function incorrectly assumed that Ether was sent to the library and threw an exception.", "severity": "low", "introduced": "0.4.0", "fixed": "0.4.2" @@ -570,8 +607,8 @@ { "uid": "SOL-2016-6", "name": "SendFailsForZeroEther", - "summary": "The send function did not provide enough gas to the recipient if no Trx was sent with it.", - "description": "The recipient of an Trx transfer automatically receives a certain amount of gas from the EVM to handle the transfer. In the case of a zero-transfer, this gas is not provided which causes the recipient to throw an exception.", + "summary": "The send function did not provide enough gas to the recipient if no Ether was sent with it.", + "description": "The recipient of an Ether transfer automatically receives a certain amount of gas from the EVM to handle the transfer. In the case of a zero-transfer, this gas is not provided which causes the recipient to throw an exception.", "severity": "low", "fixed": "0.4.0" }, diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 1a210b885c2a..ce37a10ddb4d 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,8 @@ }, "0.7.2": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1658,6 +1738,8 @@ }, "0.7.3": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1673,6 +1755,8 @@ }, "0.7.4": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1687,6 +1771,8 @@ }, "0.7.5": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1701,6 +1787,8 @@ }, "0.7.6": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1715,6 +1803,8 @@ }, "0.8.0": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1729,6 +1819,8 @@ }, "0.8.1": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1743,6 +1835,8 @@ }, "0.8.10": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1755,6 +1849,8 @@ }, "0.8.11": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1768,6 +1864,8 @@ }, "0.8.12": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1781,6 +1879,8 @@ }, "0.8.13": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1795,6 +1895,8 @@ }, "0.8.14": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1807,6 +1909,8 @@ }, "0.8.15": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1817,6 +1921,8 @@ }, "0.8.16": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1826,6 +1932,8 @@ }, "0.8.17": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1834,6 +1942,8 @@ }, "0.8.18": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1842,6 +1952,8 @@ }, "0.8.19": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1850,6 +1962,8 @@ }, "0.8.2": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1864,6 +1978,8 @@ }, "0.8.20": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess" @@ -1872,46 +1988,75 @@ }, "0.8.21": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication" ], "released": "2023-07-19" }, "0.8.22": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication" ], "released": "2023-10-25" }, "0.8.23": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2023-11-08" }, "0.8.24": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-01-25" }, "0.8.25": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-03-14" }, "0.8.26": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-05-21" }, "0.8.27": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-09-04" }, "0.8.28": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "TransientStorageClearingHelperCollision", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2024-10-09" }, "0.8.29": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "TransientStorageClearingHelperCollision", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2025-03-12" }, "0.8.3": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1924,11 +2069,51 @@ "released": "2021-03-23" }, "0.8.30": { - "bugs": [], + "bugs": [ + "UnsoundSpillInMutualRecursion", + "TransientStorageClearingHelperCollision", + "LostStorageArrayWriteOnSlotOverflow" + ], "released": "2025-05-07" }, + "0.8.31": { + "bugs": [ + "UnsoundSpillInMutualRecursion", + "TransientStorageClearingHelperCollision", + "LostStorageArrayWriteOnSlotOverflow" + ], + "released": "2025-12-03" + }, + "0.8.32": { + "bugs": [ + "UnsoundSpillInMutualRecursion", + "TransientStorageClearingHelperCollision" + ], + "released": "2025-12-18" + }, + "0.8.33": { + "bugs": [ + "UnsoundSpillInMutualRecursion", + "TransientStorageClearingHelperCollision" + ], + "released": "2025-12-18" + }, + "0.8.34": { + "bugs": [ + "UnsoundSpillInMutualRecursion" + ], + "released": "2026-02-18" + }, + "0.8.35": { + "bugs": [ + "UnsoundSpillInMutualRecursion" + ], + "released": "2026-04-29" + }, "0.8.4": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", "AbiReencodingHeadOverflowWithStaticArrayCleanup", @@ -1941,6 +2126,8 @@ }, "0.8.5": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1954,6 +2141,8 @@ }, "0.8.6": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1967,6 +2156,8 @@ }, "0.8.7": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1980,6 +2171,8 @@ }, "0.8.8": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -1994,6 +2187,8 @@ }, "0.8.9": { "bugs": [ + "UnsoundSpillInMutualRecursion", + "LostStorageArrayWriteOnSlotOverflow", "VerbatimInvalidDeduplication", "FullInlinerNonExpressionSplitArgumentEvaluationOrder", "MissingSideEffectsOnSelectorAccess", @@ -2004,4 +2199,4 @@ ], "released": "2021-09-29" } -} \ No newline at end of file +} diff --git a/libyul/optimiser/CallGraphGenerator.cpp b/libyul/optimiser/CallGraphGenerator.cpp index 9b69835dc4f1..f4b1ed6c6e41 100644 --- a/libyul/optimiser/CallGraphGenerator.cpp +++ b/libyul/optimiser/CallGraphGenerator.cpp @@ -22,10 +22,17 @@ #include #include +#include + #include +#include #include -#include +#include +#include +#include + +#include using namespace solidity; using namespace solidity::yul; @@ -33,43 +40,80 @@ using namespace solidity::util; namespace { -// TODO: This algorithm is non-optimal. -struct CallGraphCycleFinder -{ - CallGraph const& callGraph; - std::set containedInCycle{}; - std::set visited{}; - std::vector currentPath{}; - void visit(FunctionHandle const& _function) +class FunctionToIndexBiMapping +{ +public: + explicit FunctionToIndexBiMapping(std::map> const& _functionCalls) { - if (visited.count(_function)) - return; - if ( - auto it = find(currentPath.begin(), currentPath.end(), _function); - it != currentPath.end() - ) - containedInCycle.insert(it, currentPath.end()); - else + for (auto const& [function, callees]: _functionCalls) { - currentPath.emplace_back(_function); - if (callGraph.functionCalls.count(_function)) - for (auto const& child: callGraph.functionCalls.at(_function)) - visit(child); - currentPath.pop_back(); - visited.insert(_function); + if (m_functionToIndex.try_emplace(function, m_indexToFunction.size()).second) + m_indexToFunction.emplace_back(function); + for (auto const& callee: callees) + if (m_functionToIndex.try_emplace(callee, m_indexToFunction.size()).second) + m_indexToFunction.emplace_back(callee); } } + + FunctionHandle const& indexToFunction(std::size_t const _index) const + { + return m_indexToFunction.at(_index); + } + + std::size_t numFunctions() const + { + return m_indexToFunction.size(); + } + + std::size_t functionToIndex(FunctionHandle const& _functionHandle) const + { + return m_functionToIndex.at(_functionHandle); + } + +private: + std::vector m_indexToFunction; + std::map m_functionToIndex; }; + } std::set CallGraph::recursiveFunctions() const { - CallGraphCycleFinder cycleFinder{*this}; - // Visiting the root only is not enough, since there may be disconnected recursive functions. - for (auto const& call: functionCalls) - cycleFinder.visit(call.first); - return cycleFinder.containedInCycle; + // A function is recursive iff it is part of a non-trivial strongly-connected component of the call graph (a + // mutual-recursion cycle of any length) or it directly calls itself. The SCCs are computed with Tarjan's algorithm. + // Tarjan's implementation requires dense node indices in [0, N), so assign each function handle + // (both callers and callees) a consecutive index. + FunctionToIndexBiMapping const functionIndexBimap(functionCalls); + + // Build list of edges in the call graph + std::vector> indexBasedAdjacencyList(functionIndexBimap.numFunctions()); + for (auto const& [function, callees]: functionCalls) + for (auto const& callee: callees) + indexBasedAdjacencyList[functionIndexBimap.functionToIndex(function)].emplace_back(functionIndexBimap.functionToIndex(callee)); + + // Sort and deduplicate each adjacency list so the self-loop check below can use a binary search + for (auto& callees: indexBasedAdjacencyList) + { + ranges::sort(callees); + callees.erase(ranges::unique(callees), callees.end()); + } + + std::set recursiveFunctionHandleSet; + for (std::vector const& scc: util::computeStronglyConnectedComponents(indexBasedAdjacencyList)) + { + yulAssert(!scc.empty()); + if (scc.size() > 1) + // more than one element in the SCC: everything in it is mutually recursive + for (std::size_t const node: scc) + recursiveFunctionHandleSet.insert(functionIndexBimap.indexToFunction(node)); + else if (ranges::binary_search(indexBasedAdjacencyList[scc.front()], scc.front())) + // self-recursion f -> f + recursiveFunctionHandleSet.insert(functionIndexBimap.indexToFunction(scc.front())); + } + + yulAssert(!recursiveFunctionHandleSet.contains(YulName{}), "the top-level block cannot be recursive"); + return recursiveFunctionHandleSet; } CallGraph CallGraphGenerator::callGraph(Block const& _ast) @@ -99,9 +143,12 @@ void CallGraphGenerator::operator()(ForLoop const& _forLoop) void CallGraphGenerator::operator()(FunctionDefinition const& _functionDefinition) { + yulAssert( + !m_callGraph.functionCalls.contains(_functionDefinition.name), + "CallGraphGenerator requires a disambiguated AST: duplicate function name " + _functionDefinition.name.str() + "." + ); YulName previousFunction = m_currentFunction; m_currentFunction = _functionDefinition.name; - yulAssert(m_callGraph.functionCalls.count(m_currentFunction) == 0, ""); m_callGraph.functionCalls[m_currentFunction] = {}; ASTWalker::operator()(_functionDefinition); m_currentFunction = previousFunction; diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json index d722677373f0..6650da378c61 100644 --- a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/output.json @@ -1,33 +1,26 @@ { - "contracts": { - "in.sol": { - "C": { - "evm": { - "bytecode": { - "functionDebugData": { - "allocate_unbounded": { - "entryPoint": 32, - "id": null, - "parameterSlots": 0, - "returnSlots": 1 - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "entryPoint": 38, - "id": null, - "parameterSlots": 0, - "returnSlots": 0 - } - }, - "generatedSources": [], - "linkReferences": {}, - "object": "", - "opcodes":"", - "sourceMap": "567:1327:0:-:0;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;" - } - } - } + "errors": [ + { + "component": "general", + "formattedMessage": "YulException: Cannot swap Variable var_m with Variable expr_70: too deep in the stack by 1 slots in [ RET var_m var_m var_m var_m var_m var_m var_m var_m var_m expr_66 var_v15 var_v14 var_v13 var_v12 var_v11 var_v10 var_v9 var_v8 var_v7 var_v6 var_v5 var_v4 var_v3 var_v2 var_v1 expr_70 ] +memoryguard was present. + --> in.sol:46:23: + | +46 | uint256 v18 = seed[17] ^ m; + | ^^^^ + +", + "message": "Cannot swap Variable var_m with Variable expr_70: too deep in the stack by 1 slots in [ RET var_m var_m var_m var_m var_m var_m var_m var_m var_m expr_66 var_v15 var_v14 var_v13 var_v12 var_v11 var_v10 var_v9 var_v8 var_v7 var_v6 var_v5 var_v4 var_v3 var_v2 var_v1 expr_70 ] +memoryguard was present.", + "severity": "error", + "sourceLocation": { + "end": 1488, + "file": "in.sol", + "start": 1484 + }, + "type": "YulException" } - }, + ], "sources": { "in.sol": { "id": 0 diff --git a/test/libyul/yulCallGraph/intersecting_cycles.yul b/test/libyul/yulCallGraph/intersecting_cycles.yul index b38a35720136..1bbdc7429b25 100644 --- a/test/libyul/yulCallGraph/intersecting_cycles.yul +++ b/test/libyul/yulCallGraph/intersecting_cycles.yul @@ -9,4 +9,4 @@ //
: non-recursive // alpha: recursive // beta: recursive -// gamma: non-recursive +// gamma: recursive diff --git a/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul b/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul index 1e54d1c51953..d5acc1058c0c 100644 --- a/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul +++ b/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul @@ -6,7 +6,7 @@ function rim() { spoke() } } // ---- -//
: non-recursive -// hub: recursive -// spoke: recursive -// rim: recursive +//
+// hub -> spoke, rim (recursive) +// spoke -> hub (recursive) +// rim -> spoke (recursive) diff --git a/test/libyul/yulOptimizerTests/functionSpecializer/intersecting_recursive_cycles.yul b/test/libyul/yulOptimizerTests/functionSpecializer/intersecting_recursive_cycles.yul new file mode 100644 index 000000000000..9bcfd14d26a8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionSpecializer/intersecting_recursive_cycles.yul @@ -0,0 +1,35 @@ +{ + // Intersecting recursive cycles e -> b -> d -> e and e -> c -> d -> e share {d, e}, so the whole + // {e, b, c, d} set is a single strongly-connected component and all of them are recursive. + // In particular c() must be recognized as recursive and therefore left un-specialized, despite the + // constant call site c(10). This is a regression test for the call graph cycle-detection bug that + // misclassified some members of intersecting cycles as non-recursive: specializing c(10) here would + // produce code that is not equivalent to the original. + function e(n) { + if eq(n, 0) { leave } + b(sub(n, 1)) + c(sub(n, 1)) + } + function b(n) { d(sub(n, 1)) } + function c(n) { d(sub(n, 1)) } + function d(n) { e(sub(n, 1)) } + c(10) +} +// ---- +// step: functionSpecializer +// +// { +// c(10) +// function e(n) +// { +// if eq(n, 0) { leave } +// b(sub(n, 1)) +// c(sub(n, 1)) +// } +// function b(n_1) +// { d(sub(n_1, 1)) } +// function c(n_2) +// { d(sub(n_2, 1)) } +// function d(n_3) +// { e(sub(n_3, 1)) } +// } diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul index cfa226a4e50f..a875fda5280c 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/intersecting_cycles.yul @@ -53,7 +53,7 @@ // step: stackLimitEvader // // { -// mstore(0x40, memoryguard(0xa0)) +// mstore(0x40, memoryguard(128)) // ba() // function ba() // { @@ -64,7 +64,7 @@ // { ba() } // function y() // { -// mstore(0x80, calldataload(mul(1, 4))) +// let a1 := calldataload(mul(1, 4)) // let a2 := calldataload(mul(2, 4)) // let a3 := calldataload(mul(3, 4)) // let a4 := calldataload(mul(4, 4)) @@ -73,7 +73,7 @@ // let a7 := calldataload(mul(7, 4)) // let a8 := calldataload(mul(8, 4)) // let a9 := calldataload(mul(9, 4)) -// mstore(0x80, calldataload(mul(0, 4))) +// a1 := calldataload(mul(0, 4)) // let a10 := calldataload(mul(10, 4)) // let a11 := calldataload(mul(11, 4)) // let a12 := calldataload(mul(12, 4)) @@ -83,7 +83,7 @@ // let a16 := calldataload(mul(16, 4)) // let a17 := calldataload(mul(17, 4)) // z() -// sstore(0, mload(0x80)) +// sstore(0, a1) // sstore(mul(17, 4), a17) // sstore(mul(16, 4), a16) // sstore(mul(15, 4), a15) @@ -100,6 +100,6 @@ // sstore(mul(4, 4), a4) // sstore(mul(3, 4), a3) // sstore(mul(2, 4), a2) -// sstore(mul(1, 4), mload(0x80)) +// sstore(mul(1, 4), a1) // } // } From fb4726dd352e9e87de9c97a4b37429b3cefd0edc Mon Sep 17 00:00:00 2001 From: blishko Date: Mon, 29 Jun 2026 13:16:03 +0200 Subject: [PATCH 090/121] Tests: Add tests demonstrating incorrect behaviour These are tests to demonstrate incorrect processing of inheritance hierarchy in the presence of custom storage layout close to the storage end. (cherry picked from commit 2ac792906bcc3d52f99f3d4df486e15cff03ebce) --- .../args | 1 + .../err | 10 +++ .../output | 90 +++++++++++++++++++ .../stdin | 6 ++ ...tance_constructor_order_calling_revert.sol | 15 ++++ ..._constructor_order_setting_storage_var.sol | 19 ++++ ...ors_with_different_number_of_arguments.sol | 15 ++++ .../inheritance_fallback_calling_revert.sol | 28 ++++++ .../inheritance_immutables.sol | 21 +++++ .../inheritance_modifier_calling_revert.sol | 38 ++++++++ ...le_parents_constructors_with_arguments.sol | 15 ++++ .../inheritance_receive_calling_revert.sol | 28 ++++++ ...nheritance_storage_vars_initialization.sol | 25 ++++++ ...ance_calling_super_specifier_on_caller.sol | 4 + ...tance_calling_super_specifier_on_child.sol | 5 ++ 15 files changed, 320 insertions(+) create mode 100644 test/cmdlineTests/storage_layout_specifier_with_inheritance/args create mode 100644 test/cmdlineTests/storage_layout_specifier_with_inheritance/err create mode 100644 test/cmdlineTests/storage_layout_specifier_with_inheritance/output create mode 100644 test/cmdlineTests/storage_layout_specifier_with_inheritance/stdin create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol diff --git a/test/cmdlineTests/storage_layout_specifier_with_inheritance/args b/test/cmdlineTests/storage_layout_specifier_with_inheritance/args new file mode 100644 index 000000000000..23f63dd3b141 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_with_inheritance/args @@ -0,0 +1 @@ +--storage-layout --pretty-json --json-indent 4 - diff --git a/test/cmdlineTests/storage_layout_specifier_with_inheritance/err b/test/cmdlineTests/storage_layout_specifier_with_inheritance/err new file mode 100644 index 000000000000..12e97c1e44f3 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_with_inheritance/err @@ -0,0 +1,10 @@ +Warning: This contract is very close to the end of storage. This limits its future upgradability. + --> :6:17: + | +6 | contract C is B layout at 2**256 - 2**40 { uint z; } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +Note: There are 0xffFFFFfffc storage slots between this state variable and the end of storage. + --> :4:14: + | +4 | contract A { uint x; } + | ^^^^^^ diff --git a/test/cmdlineTests/storage_layout_specifier_with_inheritance/output b/test/cmdlineTests/storage_layout_specifier_with_inheritance/output new file mode 100644 index 000000000000..2b297eb3d9b7 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_with_inheritance/output @@ -0,0 +1,90 @@ + +======= :A ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 3, + "contract": ":A", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} + +======= :B ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 3, + "contract": ":B", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 8, + "contract": ":B", + "label": "y", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} + +======= :C ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 21, + "contract": ":C", + "label": "z", + "offset": 0, + "slot": "115792089237316195423570985008687907853269984665640564039457584006813618012160", + "type": "t_uint256" + }, + { + "astId": 8, + "contract": ":C", + "label": "y", + "offset": 0, + "slot": "115792089237316195423570985008687907853269984665640564039457584006813618012161", + "type": "t_uint256" + }, + { + "astId": 3, + "contract": ":C", + "label": "x", + "offset": 0, + "slot": "115792089237316195423570985008687907853269984665640564039457584006813618012162", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} diff --git a/test/cmdlineTests/storage_layout_specifier_with_inheritance/stdin b/test/cmdlineTests/storage_layout_specifier_with_inheritance/stdin new file mode 100644 index 000000000000..5d7bb66b6b79 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_with_inheritance/stdin @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract A { uint x; } +contract B is A { uint y; } +contract C is B layout at 2**256 - 2**40 { uint z; } diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol new file mode 100644 index 000000000000..608da424c2aa --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol @@ -0,0 +1,15 @@ +contract A { constructor() { revert("A"); } } +contract B is A { constructor() { revert("B"); } } +contract C1 is B layout at 2**256 - 2**42 { constructor() { revert("C"); } } +contract C2 is B { constructor() { revert("C"); } } +contract F { + function withSpecifier() public returns (string memory) { + new C1(); + } + function withoutSpecifier() public returns (string memory) { + new C2(); + } +} +// ---- +// withSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "C" +// withoutSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "A" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol new file mode 100644 index 000000000000..07943c0c4d1b --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol @@ -0,0 +1,19 @@ +contract A { uint public x; constructor() { x = 1; } } +contract B is A { constructor() { x = x * 10; } } +contract C1 is B layout at 2**256 - 2**40 { constructor() { x = x + 5; } } +contract C2 is B { constructor() { x = x + 5; } } +contract F { + function withSpecifier() public returns (uint) { + return new C1().x(); + } + function withoutSpecifier() public returns (uint) { + return new C2().x(); + } +} +// ---- +// withSpecifier() -> 5 +// gas legacy: 76868 +// gas legacy code: 30000 +// withoutSpecifier() -> 15 +// gas legacy: 77502 +// gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol new file mode 100644 index 000000000000..8ef84b119bb5 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol @@ -0,0 +1,15 @@ +contract A { constructor(uint x) {} } +contract B is A(1) { constructor(uint y, uint z) {} } +// Compilation of C1 crashes with "invalid IR generated" with `--via-ir` +//contract C1 is B(2, 3) layout at 2**256 - 2**42 { constructor() {} } +contract C2 is B(2, 3) { constructor() {} } +contract F { + //function withSpecifier() public { + // new C1(); + //} + function withoutSpecifier() public { + new C2(); + } +} +// ---- +// withoutSpecifier() -> diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol new file mode 100644 index 000000000000..9ef90e6ec9cc --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol @@ -0,0 +1,28 @@ +contract A { fallback() external virtual { revert("A"); } } +contract B is A { fallback() external override virtual { revert("B"); } } +// C1 cannot be compiled with `--via-ir` at the moment, compiler crashes because of the storage layout specifier bug +//contract C1 is B layout at 2**256 - 2**42 { fallback() external override virtual { revert("C"); } } +contract C2 is B { fallback() external override virtual { revert("C"); } } +contract F { + function decode(bytes memory data) internal returns (string memory) { + assembly { + // Shift the memory pointer forward by 4 bytes to skip the selector + data := add(data, 4) + } + return abi.decode(data, (string)); + } + //function withSpecifier() public returns (string memory) { + // (bool success, bytes memory data) = address(new C1()).call(hex"beee"); + // require(!success, "Must fail!"); + // return decode(data); + //} + function withoutSpecifier() public returns (string memory) { + (bool success, bytes memory data) = address(new C2()).call(hex"beee"); + require(!success, "Must fail!"); + return decode(data); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// withoutSpecifier() -> 0x20, 1, "C" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol new file mode 100644 index 000000000000..256102cc4807 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol @@ -0,0 +1,21 @@ +contract A { uint public immutable a = 1; } +contract B is A { uint public immutable b = 2; } +// Using specifier, `--via-ir` produces incorrect output, while legacy produces correct one. +//contract C1 is B layout at 2**256 - 2**42 { uint public immutable c = 3; } +contract C2 is B { uint public immutable c = 3; } +contract F { + //function withSpecifier() public returns(uint, uint, uint) { + // C1 c = new C1(); + // return (c.a(), c.b(), c.c()); + //} + function withoutSpecifier() public returns(uint, uint, uint) { + C2 c = new C2(); + return (c.a(), c.b(), c.c()); + } +} +// ---- +// withoutSpecifier() -> 1, 2, 3 +// gas irOptimized: 55246 +// gas irOptimized code: 45400 +// gas legacy: 56451 +// gas legacy code: 62800 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol new file mode 100644 index 000000000000..6f1eb52f3fc4 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol @@ -0,0 +1,38 @@ +contract A { + modifier m() virtual { + revert("A"); + _; + } +} +contract B is A { + modifier m() virtual override { + revert("B"); + _; + } +} +contract C1 is B layout at 2**256 - 2**42 { + function f() public m {} + modifier m() virtual override { + revert("C"); + _; + } +} +contract C2 is B { + function f() public m {} + modifier m() virtual override { + revert("C"); + _; + } +} + +contract F { + function withSpecifier() public returns (string memory) { + new C1().f(); + } + function withoutSpecifier() public returns (string memory) { + new C2().f(); + } +} +// ---- +// withSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "A" +// withoutSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "C" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol new file mode 100644 index 000000000000..1c1d754a5006 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol @@ -0,0 +1,15 @@ +contract A { constructor(uint x) {} } +contract B { constructor(uint x) {} } +// Compilation of C1 crashes with "invalid IR generated" with `--via-ir` +//contract C1 is A(2), B(3) layout at 2**256 - 2**42 { constructor(uint x) {} } +contract C2 is A(2), B(3) { constructor(uint x) {} } +contract F { + //function withSpecifier() public { + // new C1(4); + //} + function withoutSpecifier() public { + new C2(4); + } +} +// ---- +// withoutSpecifier() -> diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol new file mode 100644 index 000000000000..ffb706c40702 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol @@ -0,0 +1,28 @@ +contract A { receive() external payable virtual { revert("A"); } } +contract B is A { receive() external payable override virtual { revert("B"); } } +// C1 cannot be compiled with `via-ir` at the moment, compiler crashes because of the storage layout specifier bug +//contract C1 is B layout at 2**256 - 2**42 { receive() external payable override virtual { revert("C"); } } +contract C2 is B { receive() external payable override virtual { revert("C"); } } +contract F { + function decode(bytes memory data) internal returns (string memory) { + assembly { + // Shift the memory pointer forward by 4 bytes to skip the selector + data := add(data, 4) + } + return abi.decode(data, (string)); + } + //function withSpecifier() public returns (string memory) { + // (bool success, bytes memory data) = payable(new C1()).call{value: 0}(""); + // require(!success, "Must fail!"); + // return decode(data); + //} + function withoutSpecifier() public returns (string memory) { + (bool success, bytes memory data) = payable(new C2()).call{value: 0}(""); + require(!success, "Must fail!"); + return decode(data); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// withoutSpecifier() -> 0x20, 1, "C" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol new file mode 100644 index 000000000000..8cf33c8c219c --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol @@ -0,0 +1,25 @@ +contract A { uint public x = 1; } +contract B is A { uint public y = x * 10; } +// Using specifier, `--via-ir` and legacy produce diffrent output (incorrect in both cases). +//contract C1 is B layout at 2**256 - 2**40 { uint public z = y + 5; } +contract C2 is B { uint public z = y + 5; } +contract F { + //function withSpecifier() public returns (uint, uint, uint) { + // C1 c = new C1(); + // return (c.x(), c.y(), c.z()); + //} + function withoutSpecifier() public returns (uint, uint, uint) { + C2 c = new C2(); + return (c.x(), c.y(), c.z()); + } +} +// ---- +// withoutSpecifier() -> 1, 10, 15 +// gas irOptimized: 121728 +// gas irOptimized code: 27600 +// gas legacy: 123599 +// gas legacy code: 40400 +// gas legacyOptimized: 121916 +// gas legacyOptimized code: 20600 +// gas ssaCFGOptimized: 121687 +// gas ssaCFGOptimized code: 26200 diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol new file mode 100644 index 000000000000..b00f7f083c4a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol @@ -0,0 +1,4 @@ +contract A { function f() public virtual {} } +// Compilation of B1 currently crashes. +//contract B1 is A layout at 2**256 - 2**42 { function f() public override virtual { super.f(); } } +contract B2 is A { function f() public override virtual { super.f(); } } diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol new file mode 100644 index 000000000000..7d7b70c63aef --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol @@ -0,0 +1,5 @@ +contract A { function f() public virtual {} } +contract B is A { function f() public override virtual { super.f(); } } +//Compilation of C1 currently crashes. +//contract C1 is B layout at 2**256 - 2**42 {} +contract C2 is B {} From 500d51ce03cafe54d6ecfedce3d746aeac981c47 Mon Sep 17 00:00:00 2001 From: blishko Date: Mon, 29 Jun 2026 13:32:53 +0200 Subject: [PATCH 091/121] Analysis: Fix unintentional reversing of linearized based contracts When the compiler emits a warning about storage base location being too close to storage end, it calls a helper function to determine the last storage variable. This helper function previously unintentionally reversed the linearized based contracts annotation. The function only needs to take reversed **view**. It should not modify the underlying data. (cherry picked from commit 9fb715d81970cd316e09d023ec6d77a8a9555633) --- docs/bugs.json | 10 ++++++++ docs/bugs_by_version.json | 7 ++++++ .../analysis/PostTypeContractLevelChecker.cpp | 3 ++- .../output | 8 +++---- ...tance_constructor_order_calling_revert.sol | 2 +- ..._constructor_order_setting_storage_var.sol | 4 ++-- ...ors_with_different_number_of_arguments.sol | 10 ++++---- .../inheritance_fallback_calling_revert.sol | 14 +++++------ .../inheritance_immutables.sol | 18 ++++++++------ .../inheritance_modifier_calling_revert.sol | 2 +- ...le_parents_constructors_with_arguments.sol | 10 ++++---- .../inheritance_receive_calling_revert.sol | 14 +++++------ ...nheritance_storage_vars_initialization.sol | 24 ++++++++++++------- ...ance_calling_super_specifier_on_caller.sol | 5 ++-- ...tance_calling_super_specifier_on_child.sol | 5 ++-- 15 files changed, 84 insertions(+), 52 deletions(-) diff --git a/docs/bugs.json b/docs/bugs.json index 4710520cbee9..06a74c3b2835 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,14 @@ [ + { + "uid": "SOL-2026-3", + "name": "InheritanceOrderReversalOnStorageEndWarning", + "summary": "Emitting a warning about storage base location being too close to the storage end unintentionally reversed the ``linearizedBaseContracts`` annotation, possibly leading to miscompilation due to reversing the order in which inheritance is resolved.", + "description": "When the compiler detects that a custom layout specifier puts contract's static storage area too close to the end of the address space, it emits a warning. To make the warning more useful, the compiler tries to point at the last storage variable in that area. For this reason it walks the linearized inheritance hierarchy in reverse (from the least to the most derived). The list is calculated once and stored in an AST annotation called ``linearizedBaseContracts``. The direct cause of the bug was the fact that the code that reverses the list was doing it in place rather than on a copy, modifying the annotation. This effectively reversed the order of base contracts seen by any component that runs after layout checks: later phases of analysis, AST export, code generator, SMTChecker, etc. The observable effect was a reversed order of state variable initialization, constructor invocation, virtual function/modifier resolution, leading either to miscompilations or internal compiler errors, depending on the specific usage. Since the source of the bug was in the analysis stage, it was independent of the codegen pipeline or optimizer settings. The main condition necessary to trigger the bug was the presence of the warning in the output. The other is presence of language constructs whose evaluation depends on the inheritance order. While potential effects are very serious, this requirement excludes the vast majority of contracts as intentionally placing the storage variables in the last 2**64 slots is highly discouraged, which was actually the main reason for adding this warning.", + "link": "https://blog.soliditylang.org/2026/07/09/inheritance-order-reversal-on-storage-end-warning-bug/", + "introduced": "0.8.29", + "fixed": "0.8.36", + "severity": "medium" + }, { "uid": "SOL-2026-2", "name": "UnsoundSpillInMutualRecursion", diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index ce37a10ddb4d..0cc12bfe9eb7 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -2047,6 +2047,7 @@ }, "0.8.29": { "bugs": [ + "InheritanceOrderReversalOnStorageEndWarning", "UnsoundSpillInMutualRecursion", "TransientStorageClearingHelperCollision", "LostStorageArrayWriteOnSlotOverflow" @@ -2070,6 +2071,7 @@ }, "0.8.30": { "bugs": [ + "InheritanceOrderReversalOnStorageEndWarning", "UnsoundSpillInMutualRecursion", "TransientStorageClearingHelperCollision", "LostStorageArrayWriteOnSlotOverflow" @@ -2078,6 +2080,7 @@ }, "0.8.31": { "bugs": [ + "InheritanceOrderReversalOnStorageEndWarning", "UnsoundSpillInMutualRecursion", "TransientStorageClearingHelperCollision", "LostStorageArrayWriteOnSlotOverflow" @@ -2086,6 +2089,7 @@ }, "0.8.32": { "bugs": [ + "InheritanceOrderReversalOnStorageEndWarning", "UnsoundSpillInMutualRecursion", "TransientStorageClearingHelperCollision" ], @@ -2093,6 +2097,7 @@ }, "0.8.33": { "bugs": [ + "InheritanceOrderReversalOnStorageEndWarning", "UnsoundSpillInMutualRecursion", "TransientStorageClearingHelperCollision" ], @@ -2100,12 +2105,14 @@ }, "0.8.34": { "bugs": [ + "InheritanceOrderReversalOnStorageEndWarning", "UnsoundSpillInMutualRecursion" ], "released": "2026-02-18" }, "0.8.35": { "bugs": [ + "InheritanceOrderReversalOnStorageEndWarning", "UnsoundSpillInMutualRecursion" ], "released": "2026-04-29" diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.cpp b/libsolidity/analysis/PostTypeContractLevelChecker.cpp index c7b7b0961622..ae1246cd4141 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.cpp +++ b/libsolidity/analysis/PostTypeContractLevelChecker.cpp @@ -30,6 +30,7 @@ #include #include +#include #include @@ -155,7 +156,7 @@ namespace VariableDeclaration const* findLastStorageVariable(ContractDefinition const& _contract) { - for (ContractDefinition const* baseContract: ranges::actions::reverse(_contract.annotation().linearizedBaseContracts)) + for (ContractDefinition const* baseContract: ranges::views::reverse(_contract.annotation().linearizedBaseContracts)) for (VariableDeclaration const* stateVariable: ranges::actions::reverse(baseContract->stateVariables())) if (stateVariable->referenceLocation() == VariableDeclaration::Location::Unspecified) return stateVariable; diff --git a/test/cmdlineTests/storage_layout_specifier_with_inheritance/output b/test/cmdlineTests/storage_layout_specifier_with_inheritance/output index 2b297eb3d9b7..b9fc73291a08 100644 --- a/test/cmdlineTests/storage_layout_specifier_with_inheritance/output +++ b/test/cmdlineTests/storage_layout_specifier_with_inheritance/output @@ -56,9 +56,9 @@ Contract Storage Layout: { "storage": [ { - "astId": 21, + "astId": 3, "contract": ":C", - "label": "z", + "label": "x", "offset": 0, "slot": "115792089237316195423570985008687907853269984665640564039457584006813618012160", "type": "t_uint256" @@ -72,9 +72,9 @@ Contract Storage Layout: "type": "t_uint256" }, { - "astId": 3, + "astId": 21, "contract": ":C", - "label": "x", + "label": "z", "offset": 0, "slot": "115792089237316195423570985008687907853269984665640564039457584006813618012162", "type": "t_uint256" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol index 608da424c2aa..760439091716 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_calling_revert.sol @@ -11,5 +11,5 @@ contract F { } } // ---- -// withSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "C" +// withSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "A" // withoutSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "A" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol index 07943c0c4d1b..d9e597e62e1e 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructor_order_setting_storage_var.sol @@ -11,8 +11,8 @@ contract F { } } // ---- -// withSpecifier() -> 5 -// gas legacy: 76868 +// withSpecifier() -> 15 +// gas legacy: 77592 // gas legacy code: 30000 // withoutSpecifier() -> 15 // gas legacy: 77502 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol index 8ef84b119bb5..16394592d436 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_constructors_with_different_number_of_arguments.sol @@ -1,15 +1,15 @@ contract A { constructor(uint x) {} } contract B is A(1) { constructor(uint y, uint z) {} } -// Compilation of C1 crashes with "invalid IR generated" with `--via-ir` -//contract C1 is B(2, 3) layout at 2**256 - 2**42 { constructor() {} } +contract C1 is B(2, 3) layout at 2**256 - 2**42 { constructor() {} } contract C2 is B(2, 3) { constructor() {} } contract F { - //function withSpecifier() public { - // new C1(); - //} + function withSpecifier() public { + new C1(); + } function withoutSpecifier() public { new C2(); } } // ---- +// withSpecifier() -> // withoutSpecifier() -> diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol index 9ef90e6ec9cc..e0f0cfcfd7bd 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_fallback_calling_revert.sol @@ -1,7 +1,6 @@ contract A { fallback() external virtual { revert("A"); } } contract B is A { fallback() external override virtual { revert("B"); } } -// C1 cannot be compiled with `--via-ir` at the moment, compiler crashes because of the storage layout specifier bug -//contract C1 is B layout at 2**256 - 2**42 { fallback() external override virtual { revert("C"); } } +contract C1 is B layout at 2**256 - 2**42 { fallback() external override virtual { revert("C"); } } contract C2 is B { fallback() external override virtual { revert("C"); } } contract F { function decode(bytes memory data) internal returns (string memory) { @@ -11,11 +10,11 @@ contract F { } return abi.decode(data, (string)); } - //function withSpecifier() public returns (string memory) { - // (bool success, bytes memory data) = address(new C1()).call(hex"beee"); - // require(!success, "Must fail!"); - // return decode(data); - //} + function withSpecifier() public returns (string memory) { + (bool success, bytes memory data) = address(new C1()).call(hex"beee"); + require(!success, "Must fail!"); + return decode(data); + } function withoutSpecifier() public returns (string memory) { (bool success, bytes memory data) = address(new C2()).call(hex"beee"); require(!success, "Must fail!"); @@ -25,4 +24,5 @@ contract F { // ==== // EVMVersion: >homestead // ---- +// withSpecifier() -> 0x20, 1, "C" // withoutSpecifier() -> 0x20, 1, "C" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol index 256102cc4807..7c2d65c67681 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_immutables.sol @@ -1,21 +1,25 @@ contract A { uint public immutable a = 1; } contract B is A { uint public immutable b = 2; } -// Using specifier, `--via-ir` produces incorrect output, while legacy produces correct one. -//contract C1 is B layout at 2**256 - 2**42 { uint public immutable c = 3; } +contract C1 is B layout at 2**256 - 2**42 { uint public immutable c = 3; } contract C2 is B { uint public immutable c = 3; } contract F { - //function withSpecifier() public returns(uint, uint, uint) { - // C1 c = new C1(); - // return (c.a(), c.b(), c.c()); - //} + function withSpecifier() public returns(uint, uint, uint) { + C1 c = new C1(); + return (c.a(), c.b(), c.c()); + } function withoutSpecifier() public returns(uint, uint, uint) { C2 c = new C2(); return (c.a(), c.b(), c.c()); } } // ---- +// withSpecifier() -> 1, 2, 3 +// gas irOptimized: 55312 +// gas irOptimized code: 45400 +// gas legacy: 56473 +// gas legacy code: 62800 // withoutSpecifier() -> 1, 2, 3 -// gas irOptimized: 55246 +// gas irOptimized: 55286 // gas irOptimized code: 45400 // gas legacy: 56451 // gas legacy code: 62800 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol index 6f1eb52f3fc4..6783ce94a295 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_modifier_calling_revert.sol @@ -34,5 +34,5 @@ contract F { } } // ---- -// withSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "A" +// withSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "C" // withoutSpecifier() -> FAILURE, hex"08c379a0", 0x20, 1, "C" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol index 1c1d754a5006..e7032107d06e 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_multiple_parents_constructors_with_arguments.sol @@ -1,15 +1,15 @@ contract A { constructor(uint x) {} } contract B { constructor(uint x) {} } -// Compilation of C1 crashes with "invalid IR generated" with `--via-ir` -//contract C1 is A(2), B(3) layout at 2**256 - 2**42 { constructor(uint x) {} } +contract C1 is A(2), B(3) layout at 2**256 - 2**42 { constructor(uint x) {} } contract C2 is A(2), B(3) { constructor(uint x) {} } contract F { - //function withSpecifier() public { - // new C1(4); - //} + function withSpecifier() public { + new C1(4); + } function withoutSpecifier() public { new C2(4); } } // ---- +// withSpecifier() -> // withoutSpecifier() -> diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol index ffb706c40702..a867a6090819 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_receive_calling_revert.sol @@ -1,7 +1,6 @@ contract A { receive() external payable virtual { revert("A"); } } contract B is A { receive() external payable override virtual { revert("B"); } } -// C1 cannot be compiled with `via-ir` at the moment, compiler crashes because of the storage layout specifier bug -//contract C1 is B layout at 2**256 - 2**42 { receive() external payable override virtual { revert("C"); } } +contract C1 is B layout at 2**256 - 2**42 { receive() external payable override virtual { revert("C"); } } contract C2 is B { receive() external payable override virtual { revert("C"); } } contract F { function decode(bytes memory data) internal returns (string memory) { @@ -11,11 +10,11 @@ contract F { } return abi.decode(data, (string)); } - //function withSpecifier() public returns (string memory) { - // (bool success, bytes memory data) = payable(new C1()).call{value: 0}(""); - // require(!success, "Must fail!"); - // return decode(data); - //} + function withSpecifier() public returns (string memory) { + (bool success, bytes memory data) = payable(new C1()).call{value: 0}(""); + require(!success, "Must fail!"); + return decode(data); + } function withoutSpecifier() public returns (string memory) { (bool success, bytes memory data) = payable(new C2()).call{value: 0}(""); require(!success, "Must fail!"); @@ -25,4 +24,5 @@ contract F { // ==== // EVMVersion: >homestead // ---- +// withSpecifier() -> 0x20, 1, "C" // withoutSpecifier() -> 0x20, 1, "C" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol index 8cf33c8c219c..382c84bde695 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol @@ -1,25 +1,33 @@ contract A { uint public x = 1; } contract B is A { uint public y = x * 10; } -// Using specifier, `--via-ir` and legacy produce diffrent output (incorrect in both cases). -//contract C1 is B layout at 2**256 - 2**40 { uint public z = y + 5; } +contract C1 is B layout at 2**256 - 2**40 { uint public z = y + 5; } contract C2 is B { uint public z = y + 5; } contract F { - //function withSpecifier() public returns (uint, uint, uint) { - // C1 c = new C1(); - // return (c.x(), c.y(), c.z()); - //} + function withSpecifier() public returns (uint, uint, uint) { + C1 c = new C1(); + return (c.x(), c.y(), c.z()); + } function withoutSpecifier() public returns (uint, uint, uint) { C2 c = new C2(); return (c.x(), c.y(), c.z()); } } // ---- +// withSpecifier() -> 1, 10, 15 +// gas irOptimized: 121822 +// gas irOptimized code: 30800 +// gas legacy: 123715 +// gas legacy code: 63400 +// gas legacyOptimized: 121966 +// gas legacyOptimized code: 23800 +// gas ssaCFGOptimized: 121771 +// gas ssaCFGOptimized code: 29400 // withoutSpecifier() -> 1, 10, 15 -// gas irOptimized: 121728 +// gas irOptimized: 121768 // gas irOptimized code: 27600 // gas legacy: 123599 // gas legacy code: 40400 // gas legacyOptimized: 121916 // gas legacyOptimized code: 20600 -// gas ssaCFGOptimized: 121687 +// gas ssaCFGOptimized: 121722 // gas ssaCFGOptimized code: 26200 diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol index b00f7f083c4a..801aa813091b 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_caller.sol @@ -1,4 +1,5 @@ contract A { function f() public virtual {} } -// Compilation of B1 currently crashes. -//contract B1 is A layout at 2**256 - 2**42 { function f() public override virtual { super.f(); } } +contract B1 is A layout at 2**256 - 2**42 { function f() public override virtual { super.f(); } } contract B2 is A { function f() public override virtual { super.f(); } } +// ---- +// Warning 3495: (63-87): This contract is very close to the end of storage. This limits its future upgradability. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol index 7d7b70c63aef..030a54f084a0 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheritance_calling_super_specifier_on_child.sol @@ -1,5 +1,6 @@ contract A { function f() public virtual {} } contract B is A { function f() public override virtual { super.f(); } } -//Compilation of C1 currently crashes. -//contract C1 is B layout at 2**256 - 2**42 {} +contract C1 is B layout at 2**256 - 2**42 {} contract C2 is B {} +// ---- +// Warning 3495: (135-159): This contract is very close to the end of storage. This limits its future upgradability. From 3d567ea18fcb1eba4626b3fc16abf02d4745288e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 29 Jun 2026 10:26:47 +0200 Subject: [PATCH 092/121] Add disambiguator prerequisite to call graph generator (cherry picked from commit 58bc9f8f20a363cdd1e741c8a4a302184d78a7b9) --- libyul/optimiser/CallGraphGenerator.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libyul/optimiser/CallGraphGenerator.h b/libyul/optimiser/CallGraphGenerator.h index 722cbba4a796..ca3f11434eba 100644 --- a/libyul/optimiser/CallGraphGenerator.h +++ b/libyul/optimiser/CallGraphGenerator.h @@ -17,6 +17,8 @@ // SPDX-License-Identifier: GPL-3.0 /** * Specific AST walker that generates the call graph. + * + * Prerequisites: Disambiguator */ #pragma once From e1690728493cf890527ba9a78924e01fecaef9b5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:55:40 +0200 Subject: [PATCH 093/121] Call graph test: output the whole call graph (cherry picked from commit 56edc07403ac1e37650e9915e9a8425a594ab5f8) --- test/libyul/CallGraphTest.cpp | 44 +++++++++++++++---- test/libyul/yulCallGraph/ambiguous_names.yul | 2 +- .../yulCallGraph/ambiguous_names_nested.yul | 2 +- .../branching_into_and_out_of_scc.yul | 8 ++-- .../builtin_in_recursive_cycle.yul | 8 ++++ test/libyul/yulCallGraph/caller_into_scc.yul | 8 ++-- .../yulCallGraph/direct_plus_mutual.yul | 8 ++-- test/libyul/yulCallGraph/direct_self_call.yul | 4 +- .../libyul/yulCallGraph/duplicate_callees.yul | 6 +-- .../yulCallGraph/intersecting_cycles.yul | 8 ++-- .../intersecting_cycles_visitation_order.yul | 6 +-- test/libyul/yulCallGraph/leaf.yul | 4 +- test/libyul/yulCallGraph/loop_in_main.yul | 5 +++ .../yulCallGraph/loop_in_nested_function.yul | 14 ++++++ test/libyul/yulCallGraph/mixed.yul | 8 ++-- .../yulCallGraph/multi_callee_three_scc.yul | 8 ++-- .../multiple_distinct_callees.yul | 8 ++-- test/libyul/yulCallGraph/multiple_loops.yul | 13 ++++++ .../yulCallGraph/mutual_three_cycle.yul | 8 ++-- test/libyul/yulCallGraph/mutual_two_cycle.yul | 6 +-- test/libyul/yulCallGraph/nested_functions.yul | 8 ++-- .../yulCallGraph/non_recursive_chain.yul | 8 ++-- test/libyul/yulCallGraph/self_and_other.yul | 6 +-- test/libyul/yulCallGraph/shared_callee.yul | 8 ++-- 24 files changed, 137 insertions(+), 71 deletions(-) create mode 100644 test/libyul/yulCallGraph/builtin_in_recursive_cycle.yul create mode 100644 test/libyul/yulCallGraph/loop_in_main.yul create mode 100644 test/libyul/yulCallGraph/loop_in_nested_function.yul create mode 100644 test/libyul/yulCallGraph/multiple_loops.yul diff --git a/test/libyul/CallGraphTest.cpp b/test/libyul/CallGraphTest.cpp index 5fad64777b44..b1eb34468284 100644 --- a/test/libyul/CallGraphTest.cpp +++ b/test/libyul/CallGraphTest.cpp @@ -25,14 +25,21 @@ #include #include +#include +#include +#include #include +#include #include #include +#include + #include using namespace solidity; +using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; using namespace solidity::yul::test; @@ -87,23 +94,42 @@ TestCase::TestResult CallGraphTest::run(std::ostream& _stream, std::string const try { CallGraph const callGraph = CallGraphGenerator::callGraph(root); - std::set const recursive = callGraph.recursiveFunctions(); - - auto classification = [&](FunctionHandle const& _function) { - return recursive.contains(_function) ? "recursive" : "non-recursive"; + std::set const recursiveFunctionHandles = callGraph.recursiveFunctions(); + Dialect const& dialect = yulStack.dialect(); + + auto printNode = [&](YulName const _name) { + FunctionHandle const handle{_name}; + out << (_name == YulName{} ? "
" : _name.str()); + + std::vector annotations; + if (recursiveFunctionHandles.contains(handle)) + annotations.emplace_back("recursive"); + if (callGraph.functionsWithLoops.contains(_name)) + annotations.emplace_back("loops"); + if (!annotations.empty()) + out << " (" << joinHumanReadable(annotations) << ")"; + + std::vector renderedCallees; + for (FunctionHandle const& callee: callGraph.functionCalls.at(handle)) + renderedCallees.emplace_back(resolveFunctionName(callee, dialect)); + if (!renderedCallees.empty()) + out << " -> " << joinHumanReadable(renderedCallees); + + out << "\n"; }; FunctionNameCollector collector; collector(root); - // The outermost (non-function) context is denoted by the empty name in the call graph. - out << "
: " << classification(YulName{}) << "\n"; + printNode(YulName{}); for (YulName const& name: collector.names) - out << name.str() << ": " << classification(name) << "\n"; + printNode(name); + + yulAssert(!recursiveFunctionHandles.contains(YulName{}), "main cannot be recursive"); } - catch (langutil::InternalCompilerError const& _error) + catch (YulAssertion const& _error) { - out << "InternalCompilerError: " << (_error.comment() ? *_error.comment() : "") << "\n"; + out << "YulAssertion: " << (_error.comment() ? *_error.comment() : "") << "\n"; } m_obtainedResult = out.str(); diff --git a/test/libyul/yulCallGraph/ambiguous_names.yul b/test/libyul/yulCallGraph/ambiguous_names.yul index f8cf3924360e..4cb2703f0e22 100644 --- a/test/libyul/yulCallGraph/ambiguous_names.yul +++ b/test/libyul/yulCallGraph/ambiguous_names.yul @@ -3,4 +3,4 @@ { function f() {} } } // ---- -// InternalCompilerError: CallGraphGenerator requires a disambiguated AST: duplicate function name f. +// YulAssertion: CallGraphGenerator requires a disambiguated AST: duplicate function name f. diff --git a/test/libyul/yulCallGraph/ambiguous_names_nested.yul b/test/libyul/yulCallGraph/ambiguous_names_nested.yul index 4cc98c7e1097..b4df07554769 100644 --- a/test/libyul/yulCallGraph/ambiguous_names_nested.yul +++ b/test/libyul/yulCallGraph/ambiguous_names_nested.yul @@ -9,4 +9,4 @@ } } // ---- -// InternalCompilerError: CallGraphGenerator requires a disambiguated AST: duplicate function name g. +// YulAssertion: CallGraphGenerator requires a disambiguated AST: duplicate function name g. diff --git a/test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul b/test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul index 82eccf25b6f4..50d500e8c3a6 100644 --- a/test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul +++ b/test/libyul/yulCallGraph/branching_into_and_out_of_scc.yul @@ -7,7 +7,7 @@ function h() {} } // ---- -//
: non-recursive -// f: recursive -// g: recursive -// h: non-recursive +//
+// f (recursive) -> g, h +// g (recursive) -> f +// h diff --git a/test/libyul/yulCallGraph/builtin_in_recursive_cycle.yul b/test/libyul/yulCallGraph/builtin_in_recursive_cycle.yul new file mode 100644 index 000000000000..018bdd9c7771 --- /dev/null +++ b/test/libyul/yulCallGraph/builtin_in_recursive_cycle.yul @@ -0,0 +1,8 @@ +{ + function f() { g() mstore(0, 1) } + function g() { f() } +} +// ---- +//
+// f (recursive) -> g, mstore +// g (recursive) -> f diff --git a/test/libyul/yulCallGraph/caller_into_scc.yul b/test/libyul/yulCallGraph/caller_into_scc.yul index 4167f3caf651..b8007d9bf320 100644 --- a/test/libyul/yulCallGraph/caller_into_scc.yul +++ b/test/libyul/yulCallGraph/caller_into_scc.yul @@ -4,7 +4,7 @@ function h() { g() } } // ---- -//
: non-recursive -// f: non-recursive -// g: recursive -// h: recursive +//
+// f -> g +// g (recursive) -> h +// h (recursive) -> g diff --git a/test/libyul/yulCallGraph/direct_plus_mutual.yul b/test/libyul/yulCallGraph/direct_plus_mutual.yul index f75690c6ba32..0d52709bef1e 100644 --- a/test/libyul/yulCallGraph/direct_plus_mutual.yul +++ b/test/libyul/yulCallGraph/direct_plus_mutual.yul @@ -4,7 +4,7 @@ function h() { g() } } // ---- -//
: non-recursive -// f: recursive -// g: recursive -// h: recursive +//
+// f (recursive) -> f +// g (recursive) -> h +// h (recursive) -> g diff --git a/test/libyul/yulCallGraph/direct_self_call.yul b/test/libyul/yulCallGraph/direct_self_call.yul index 7a57413da61b..0a902ab41c00 100644 --- a/test/libyul/yulCallGraph/direct_self_call.yul +++ b/test/libyul/yulCallGraph/direct_self_call.yul @@ -2,5 +2,5 @@ function f() { f() } } // ---- -//
: non-recursive -// f: recursive +//
+// f (recursive) -> f diff --git a/test/libyul/yulCallGraph/duplicate_callees.yul b/test/libyul/yulCallGraph/duplicate_callees.yul index 549ca59daa05..df6950c6607e 100644 --- a/test/libyul/yulCallGraph/duplicate_callees.yul +++ b/test/libyul/yulCallGraph/duplicate_callees.yul @@ -6,6 +6,6 @@ function g() {} } // ---- -//
: non-recursive -// f: non-recursive -// g: non-recursive +//
+// f -> g +// g diff --git a/test/libyul/yulCallGraph/intersecting_cycles.yul b/test/libyul/yulCallGraph/intersecting_cycles.yul index 1bbdc7429b25..baaa4ecaef7a 100644 --- a/test/libyul/yulCallGraph/intersecting_cycles.yul +++ b/test/libyul/yulCallGraph/intersecting_cycles.yul @@ -6,7 +6,7 @@ function gamma() { beta() } } // ---- -//
: non-recursive -// alpha: recursive -// beta: recursive -// gamma: recursive +//
+// alpha (recursive) -> beta, gamma +// beta (recursive) -> alpha +// gamma (recursive) -> beta diff --git a/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul b/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul index d5acc1058c0c..3ae2e10fc95f 100644 --- a/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul +++ b/test/libyul/yulCallGraph/intersecting_cycles_visitation_order.yul @@ -7,6 +7,6 @@ } // ---- //
-// hub -> spoke, rim (recursive) -// spoke -> hub (recursive) -// rim -> spoke (recursive) +// hub (recursive) -> spoke, rim +// spoke (recursive) -> hub +// rim (recursive) -> spoke diff --git a/test/libyul/yulCallGraph/leaf.yul b/test/libyul/yulCallGraph/leaf.yul index b44705017a74..06a0ba5ad89c 100644 --- a/test/libyul/yulCallGraph/leaf.yul +++ b/test/libyul/yulCallGraph/leaf.yul @@ -2,5 +2,5 @@ function f() {} } // ---- -//
: non-recursive -// f: non-recursive +//
+// f diff --git a/test/libyul/yulCallGraph/loop_in_main.yul b/test/libyul/yulCallGraph/loop_in_main.yul new file mode 100644 index 000000000000..debeabb9cf52 --- /dev/null +++ b/test/libyul/yulCallGraph/loop_in_main.yul @@ -0,0 +1,5 @@ +{ + for {} 1 {} {} +} +// ---- +//
(loops) diff --git a/test/libyul/yulCallGraph/loop_in_nested_function.yul b/test/libyul/yulCallGraph/loop_in_nested_function.yul new file mode 100644 index 000000000000..064933b5f1c0 --- /dev/null +++ b/test/libyul/yulCallGraph/loop_in_nested_function.yul @@ -0,0 +1,14 @@ +{ + function outer() { + function inner() { + for {} 1 {} {} + outer() + } + inner() + } + outer() +} +// ---- +//
-> outer +// outer (recursive) -> inner +// inner (recursive, loops) -> outer diff --git a/test/libyul/yulCallGraph/mixed.yul b/test/libyul/yulCallGraph/mixed.yul index e1bd7247fa38..c3541316f360 100644 --- a/test/libyul/yulCallGraph/mixed.yul +++ b/test/libyul/yulCallGraph/mixed.yul @@ -4,7 +4,7 @@ function h() {} } // ---- -//
: non-recursive -// f: recursive -// g: recursive -// h: non-recursive +//
+// f (recursive) -> g +// g (recursive) -> f +// h diff --git a/test/libyul/yulCallGraph/multi_callee_three_scc.yul b/test/libyul/yulCallGraph/multi_callee_three_scc.yul index dd1396a6e314..0d787837a7ee 100644 --- a/test/libyul/yulCallGraph/multi_callee_three_scc.yul +++ b/test/libyul/yulCallGraph/multi_callee_three_scc.yul @@ -7,7 +7,7 @@ function c() { b() } } // ---- -//
: non-recursive -// a: recursive -// b: recursive -// c: recursive +//
+// a (recursive) -> b, c +// b (recursive) -> a +// c (recursive) -> b diff --git a/test/libyul/yulCallGraph/multiple_distinct_callees.yul b/test/libyul/yulCallGraph/multiple_distinct_callees.yul index e67e01ca98f4..c08aba6e68d0 100644 --- a/test/libyul/yulCallGraph/multiple_distinct_callees.yul +++ b/test/libyul/yulCallGraph/multiple_distinct_callees.yul @@ -7,7 +7,7 @@ function h() {} } // ---- -//
: non-recursive -// f: non-recursive -// g: non-recursive -// h: non-recursive +//
+// f -> g, h +// g +// h diff --git a/test/libyul/yulCallGraph/multiple_loops.yul b/test/libyul/yulCallGraph/multiple_loops.yul new file mode 100644 index 000000000000..144e638de251 --- /dev/null +++ b/test/libyul/yulCallGraph/multiple_loops.yul @@ -0,0 +1,13 @@ +{ + for {} 1 {} {} + function f() { + for {} 1 {} { + for {} 1 {} {} + } + } + function g() {} +} +// ---- +//
(loops) +// f (loops) +// g diff --git a/test/libyul/yulCallGraph/mutual_three_cycle.yul b/test/libyul/yulCallGraph/mutual_three_cycle.yul index 1cdeb220de2b..f2d4af836885 100644 --- a/test/libyul/yulCallGraph/mutual_three_cycle.yul +++ b/test/libyul/yulCallGraph/mutual_three_cycle.yul @@ -4,7 +4,7 @@ function h() { f() } } // ---- -//
: non-recursive -// f: recursive -// g: recursive -// h: recursive +//
+// f (recursive) -> g +// g (recursive) -> h +// h (recursive) -> f diff --git a/test/libyul/yulCallGraph/mutual_two_cycle.yul b/test/libyul/yulCallGraph/mutual_two_cycle.yul index 123e266982cf..cc187f1c140f 100644 --- a/test/libyul/yulCallGraph/mutual_two_cycle.yul +++ b/test/libyul/yulCallGraph/mutual_two_cycle.yul @@ -3,6 +3,6 @@ function g() { f() } } // ---- -//
: non-recursive -// f: recursive -// g: recursive +//
+// f (recursive) -> g +// g (recursive) -> f diff --git a/test/libyul/yulCallGraph/nested_functions.yul b/test/libyul/yulCallGraph/nested_functions.yul index 8bd506003842..5e7068b758fd 100644 --- a/test/libyul/yulCallGraph/nested_functions.yul +++ b/test/libyul/yulCallGraph/nested_functions.yul @@ -10,7 +10,7 @@ a() } // ---- -//
: non-recursive -// a: recursive -// b: recursive -// c: recursive +//
-> a +// a (recursive) -> b +// b (recursive) -> c +// c (recursive) -> a diff --git a/test/libyul/yulCallGraph/non_recursive_chain.yul b/test/libyul/yulCallGraph/non_recursive_chain.yul index 20086c873c71..6d3f95ef1a5b 100644 --- a/test/libyul/yulCallGraph/non_recursive_chain.yul +++ b/test/libyul/yulCallGraph/non_recursive_chain.yul @@ -4,7 +4,7 @@ function h() {} } // ---- -//
: non-recursive -// f: non-recursive -// g: non-recursive -// h: non-recursive +//
+// f -> g +// g -> h +// h diff --git a/test/libyul/yulCallGraph/self_and_other.yul b/test/libyul/yulCallGraph/self_and_other.yul index be843421f297..f60f8723d946 100644 --- a/test/libyul/yulCallGraph/self_and_other.yul +++ b/test/libyul/yulCallGraph/self_and_other.yul @@ -6,6 +6,6 @@ function g() {} } // ---- -//
: non-recursive -// f: recursive -// g: non-recursive +//
+// f (recursive) -> f, g +// g diff --git a/test/libyul/yulCallGraph/shared_callee.yul b/test/libyul/yulCallGraph/shared_callee.yul index 4b28e34f2b49..88776dd0a912 100644 --- a/test/libyul/yulCallGraph/shared_callee.yul +++ b/test/libyul/yulCallGraph/shared_callee.yul @@ -4,7 +4,7 @@ function h() {} } // ---- -//
: non-recursive -// f: non-recursive -// g: non-recursive -// h: non-recursive +//
+// f -> h +// g -> h +// h From 0758b9e0012a3f9ae227d205df942013bf535d5f Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 6 Jul 2026 10:43:18 +0200 Subject: [PATCH 094/121] Add `resolveFunctionName` overload dealing with instances of `FunctionHandle` to utilities (cherry picked from commit 47e36a38bc869674751bee0990df83984b195b74) --- libyul/Utilities.cpp | 9 +++++++++ libyul/Utilities.h | 1 + 2 files changed, 10 insertions(+) diff --git a/libyul/Utilities.cpp b/libyul/Utilities.cpp index e7caf1b2dff4..5c87cb75a228 100644 --- a/libyul/Utilities.cpp +++ b/libyul/Utilities.cpp @@ -251,6 +251,15 @@ std::string_view yul::resolveFunctionName(FunctionName const& _functionName, Dia return std::visit(visitor, _functionName); } +std::string_view yul::resolveFunctionName(FunctionHandle const& _functionHandle, Dialect const& _dialect) +{ + GenericVisitor visitor{ + [&](YulName const& _name) -> std::string const& { return _name.str(); }, + [&](BuiltinHandle const& _handle) -> std::string const& { return _dialect.builtin(_handle).name; } + }; + return std::visit(visitor, _functionHandle); +} + BuiltinFunction const* yul::resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect) { GenericVisitor visitor{ diff --git a/libyul/Utilities.h b/libyul/Utilities.h index 64b5f456ac1f..f3def59ab4f5 100644 --- a/libyul/Utilities.h +++ b/libyul/Utilities.h @@ -89,6 +89,7 @@ struct SwitchCaseCompareByLiteralValue }; std::string_view resolveFunctionName(FunctionName const& _functionName, Dialect const& _dialect); +std::string_view resolveFunctionName(FunctionHandle const& _functionHandle, Dialect const& _dialect); BuiltinFunction const* resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect); BuiltinFunctionForEVM const* resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect); From 28cc279841aa2754f19152f43850c1fc3a57dfca Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 6 Jul 2026 10:54:09 +0200 Subject: [PATCH 095/121] Yul: Call graph generator asserts that builtins are never recursive (cherry picked from commit 422fe848b5c57f2b99632d990a9ecce7ca70239e) --- libyul/optimiser/CallGraphGenerator.cpp | 2 ++ libyul/optimiser/CallGraphGenerator.h | 3 +++ test/libyul/yulCallGraph/builtin_call.yul | 9 +++++++++ 3 files changed, 14 insertions(+) create mode 100644 test/libyul/yulCallGraph/builtin_call.yul diff --git a/libyul/optimiser/CallGraphGenerator.cpp b/libyul/optimiser/CallGraphGenerator.cpp index f4b1ed6c6e41..3316038cbf36 100644 --- a/libyul/optimiser/CallGraphGenerator.cpp +++ b/libyul/optimiser/CallGraphGenerator.cpp @@ -113,6 +113,8 @@ std::set CallGraph::recursiveFunctions() const } yulAssert(!recursiveFunctionHandleSet.contains(YulName{}), "the top-level block cannot be recursive"); + for (FunctionHandle const& recursiveFunction: recursiveFunctionHandleSet) + yulAssert(std::holds_alternative(recursiveFunction), "a builtin cannot be recursive"); return recursiveFunctionHandleSet; } diff --git a/libyul/optimiser/CallGraphGenerator.h b/libyul/optimiser/CallGraphGenerator.h index ca3f11434eba..bb5adb235e3b 100644 --- a/libyul/optimiser/CallGraphGenerator.h +++ b/libyul/optimiser/CallGraphGenerator.h @@ -40,6 +40,9 @@ struct CallGraph /// @returns the set of functions contained in cycles in the call graph, i.e. /// functions that are part of a (mutual) recursion. /// Note that this does not include functions that merely call recursive functions. + /// Postcondition: the result never contains a builtin. At Yul level builtins cannot call other + /// functions, so they have no outgoing call-graph edges and can be neither mutually nor directly + /// recursive. std::set recursiveFunctions() const; }; diff --git a/test/libyul/yulCallGraph/builtin_call.yul b/test/libyul/yulCallGraph/builtin_call.yul new file mode 100644 index 000000000000..8a38e75cac61 --- /dev/null +++ b/test/libyul/yulCallGraph/builtin_call.yul @@ -0,0 +1,9 @@ +{ + function f() { + mstore(0, 1) + } + f() +} +// ---- +//
-> f +// f -> mstore From 4adcd1ae65a48d5078409cd87a31749a0e99a0d5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 6 Jul 2026 15:37:56 +0200 Subject: [PATCH 096/121] Yul: Call graph generator raises proper exception if input is not disambiguated (cherry picked from commit d32ee36ca1b42d99a89d2af1d5d9de3db9235e7d) --- libyul/optimiser/CallGraphGenerator.cpp | 3 ++- libyul/optimiser/CallGraphGenerator.h | 4 ++++ test/libyul/CallGraphTest.cpp | 4 ++-- test/libyul/yulCallGraph/ambiguous_names.yul | 2 +- test/libyul/yulCallGraph/ambiguous_names_nested.yul | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libyul/optimiser/CallGraphGenerator.cpp b/libyul/optimiser/CallGraphGenerator.cpp index 3316038cbf36..15a31d05c7f6 100644 --- a/libyul/optimiser/CallGraphGenerator.cpp +++ b/libyul/optimiser/CallGraphGenerator.cpp @@ -145,8 +145,9 @@ void CallGraphGenerator::operator()(ForLoop const& _forLoop) void CallGraphGenerator::operator()(FunctionDefinition const& _functionDefinition) { - yulAssert( + solRequire( !m_callGraph.functionCalls.contains(_functionDefinition.name), + InputNotDisambiguatedException, "CallGraphGenerator requires a disambiguated AST: duplicate function name " + _functionDefinition.name.str() + "." ); YulName previousFunction = m_currentFunction; diff --git a/libyul/optimiser/CallGraphGenerator.h b/libyul/optimiser/CallGraphGenerator.h index bb5adb235e3b..f89e5a04cafa 100644 --- a/libyul/optimiser/CallGraphGenerator.h +++ b/libyul/optimiser/CallGraphGenerator.h @@ -52,10 +52,14 @@ struct CallGraph * It also generates information about which functions contain for loops. * * The outermost (non-function) context is denoted by the empty string. + * + * @throws InputNotDisambiguatedException if input is not disambiguated */ class CallGraphGenerator: public ASTWalker { public: + struct InputNotDisambiguatedException: virtual YulException {}; + static CallGraph callGraph(Block const& _ast); using ASTWalker::operator(); diff --git a/test/libyul/CallGraphTest.cpp b/test/libyul/CallGraphTest.cpp index b1eb34468284..f55ff2475144 100644 --- a/test/libyul/CallGraphTest.cpp +++ b/test/libyul/CallGraphTest.cpp @@ -127,9 +127,9 @@ TestCase::TestResult CallGraphTest::run(std::ostream& _stream, std::string const yulAssert(!recursiveFunctionHandles.contains(YulName{}), "main cannot be recursive"); } - catch (YulAssertion const& _error) + catch (CallGraphGenerator::InputNotDisambiguatedException const& _exception) { - out << "YulAssertion: " << (_error.comment() ? *_error.comment() : "") << "\n"; + out << "InputNotDisambiguatedException: " << (_exception.comment() ? *_exception.comment() : "") << "\n"; } m_obtainedResult = out.str(); diff --git a/test/libyul/yulCallGraph/ambiguous_names.yul b/test/libyul/yulCallGraph/ambiguous_names.yul index 4cb2703f0e22..bf1bdbd7ca35 100644 --- a/test/libyul/yulCallGraph/ambiguous_names.yul +++ b/test/libyul/yulCallGraph/ambiguous_names.yul @@ -3,4 +3,4 @@ { function f() {} } } // ---- -// YulAssertion: CallGraphGenerator requires a disambiguated AST: duplicate function name f. +// InputNotDisambiguatedException: CallGraphGenerator requires a disambiguated AST: duplicate function name f. diff --git a/test/libyul/yulCallGraph/ambiguous_names_nested.yul b/test/libyul/yulCallGraph/ambiguous_names_nested.yul index b4df07554769..3a843bdad9c5 100644 --- a/test/libyul/yulCallGraph/ambiguous_names_nested.yul +++ b/test/libyul/yulCallGraph/ambiguous_names_nested.yul @@ -9,4 +9,4 @@ } } // ---- -// YulAssertion: CallGraphGenerator requires a disambiguated AST: duplicate function name g. +// InputNotDisambiguatedException: CallGraphGenerator requires a disambiguated AST: duplicate function name g. From 6fa56910ad39e879aa5b745873fbe32c6bab9390 Mon Sep 17 00:00:00 2001 From: Asuka Date: Thu, 16 Jul 2026 16:40:36 +0800 Subject: [PATCH 097/121] tests: adapt security backports to TRON 0.8.30 (cherry picked from commit 11815d27cdceaf8e4fb242216f0511c9706b2047) --- .../args | 2 +- .../output | 40 ++++++++++++++++--- ...nheritance_storage_vars_initialization.sol | 4 -- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/test/cmdlineTests/storage_transient_storage_collision_ir_output/args b/test/cmdlineTests/storage_transient_storage_collision_ir_output/args index b7ec904f1024..1b58291152e4 100644 --- a/test/cmdlineTests/storage_transient_storage_collision_ir_output/args +++ b/test/cmdlineTests/storage_transient_storage_collision_ir_output/args @@ -1 +1 @@ ---ir-optimized --evm-version cancun --debug-info none +--ir-optimized --evm-version cancun --debug-info none --no-cbor-metadata diff --git a/test/cmdlineTests/storage_transient_storage_collision_ir_output/output b/test/cmdlineTests/storage_transient_storage_collision_ir_output/output index dd8abeb333b0..50f2fcb90fc7 100644 --- a/test/cmdlineTests/storage_transient_storage_collision_ir_output/output +++ b/test/cmdlineTests/storage_transient_storage_collision_ir_output/output @@ -6,7 +6,15 @@ object "C_25" { mstore(64, memoryguard(0x80)) if callvalue() { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + revert_error_8061d93638ee074115f764ac3d48f9e554bb1b90dfef10edac8a99bf7cd9567b() + } + if calltokenid() + { + revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() + } + if calltokenvalue() + { + revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() } constructor_C() let _1 := allocate_unbounded() @@ -15,7 +23,9 @@ object "C_25" { } function allocate_unbounded() -> memPtr { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + function revert_error_8061d93638ee074115f764ac3d48f9e554bb1b90dfef10edac8a99bf7cd9567b() + { revert(0, 0) } + function revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() { revert(0, 0) } function shift_left(value) -> newValue { newValue := shl(0, value) } @@ -68,7 +78,9 @@ object "C_25" { { newValue := shr(224, value) } function allocate_unbounded() -> memPtr { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + function revert_error_8061d93638ee074115f764ac3d48f9e554bb1b90dfef10edac8a99bf7cd9567b() + { revert(0, 0) } + function revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() { revert(0, 0) } function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { revert(0, 0) } @@ -94,7 +106,15 @@ object "C_25" { { if callvalue() { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + revert_error_8061d93638ee074115f764ac3d48f9e554bb1b90dfef10edac8a99bf7cd9567b() + } + if calltokenid() + { + revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() + } + if calltokenvalue() + { + revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() } abi_decode(4, calldatasize()) let ret := fun_foo() @@ -124,7 +144,15 @@ object "C_25" { { if callvalue() { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + revert_error_8061d93638ee074115f764ac3d48f9e554bb1b90dfef10edac8a99bf7cd9567b() + } + if calltokenid() + { + revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() + } + if calltokenvalue() + { + revert_error_9a62d7e684059bba6a84639281e9dae3baecf10b1b86b3ab661f6dcc72bcade3() } abi_decode(4, calldatasize()) let ret := getter_fun_varStorage() @@ -219,6 +247,6 @@ object "C_25" { leave } } - data ".metadata" hex"" + data ".metadata" hex"" } } diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol index 382c84bde695..87fbe48bc973 100644 --- a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_storage_vars_initialization.sol @@ -20,8 +20,6 @@ contract F { // gas legacy code: 63400 // gas legacyOptimized: 121966 // gas legacyOptimized code: 23800 -// gas ssaCFGOptimized: 121771 -// gas ssaCFGOptimized code: 29400 // withoutSpecifier() -> 1, 10, 15 // gas irOptimized: 121768 // gas irOptimized code: 27600 @@ -29,5 +27,3 @@ contract F { // gas legacy code: 40400 // gas legacyOptimized: 121916 // gas legacyOptimized code: 20600 -// gas ssaCFGOptimized: 121722 -// gas ssaCFGOptimized code: 26200 From 918c6e6b7794aeff524667cbb60edb47b4eed7ae Mon Sep 17 00:00:00 2001 From: Asuka Date: Thu, 16 Jul 2026 10:55:41 +0800 Subject: [PATCH 098/121] ci: sync GitHub build images with CircleCI --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 98af246c1b82..15ef9b29e35f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,8 +86,8 @@ jobs: CPUs: 10 container: - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-3 - image: solbuildpackpusher/solidity-buildpack-deps@sha256:ef6a91d7f1434c67fb9e05c6136d80f71c0ad9198479e1a88e3437680993cda4 + # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404-6 + image: ghcr.io/argotorg/solidity-buildpack-deps@sha256:c0412c53e59ce0c96bde4c08e7332ea12e4cadba9bbac829621947897fa21272 steps: - name: Checkout code @@ -119,9 +119,9 @@ jobs: CPUs: 5 container: - # solbuildpackpusher/solidity-buildpack-deps:emscripten-20 + # ghcr.io/argotorg/solidity-buildpack-deps:emscripten-21 # NOTE: Keep in sync with the digest in scripts/build_emscripten.sh - image: solbuildpackpusher/solidity-buildpack-deps@sha256:98f963ed799a0d206ef8e7b5475f847e0dea53b7fdea9618bbc6106a62730bd2 + image: ghcr.io/argotorg/solidity-buildpack-deps@sha256:fc53d68a4680ffa7d5f70164e13a903478964f15bcc07434d74833a05f4fbc19 steps: - name: Checkout code From 82ee92087565aba1a9062ed2ba77ae5c7522d644 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 21 Jul 2026 17:46:07 +0800 Subject: [PATCH 099/121] ci: add Linux ARM64 release binary --- .github/workflows/build.yml | 54 ++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15ef9b29e35f..e5f7c4717077 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -110,6 +110,40 @@ jobs: path: github/solc-static-linux key: solc-linux-${{ github.run_id }} + b_linux_arm: + runs-on: ubuntu-24.04-arm + + env: + CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DSOLC_LINK_STATIC=ON + TERM: xterm + MAKEFLAGS: -j 4 + CPUs: 4 + + container: + # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404.arm-1 + image: ghcr.io/argotorg/solidity-buildpack-deps@sha256:6cdb928fa8743d0b5d515c2c489b8d545c541f2370af28d5d3a71532056a0f22 + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Fix git safe directory + run: git config --global --add safe.directory '*' + + - name: Run build script + run: .github/workflows/build.sh + + - name: Prepare artifact for caching + run: | + mkdir github/ + cp build/solc/solc github/solc-static-linux-arm + + - name: Save artifact to cache + uses: actions/cache/save@v5 + with: + path: github/solc-static-linux-arm + key: solc-linux-arm-${{ github.run_id }} + b_ems: runs-on: [ self-hosted, Linux, for-ems ] @@ -145,7 +179,7 @@ jobs: key: solc-ems-${{ github.run_id }} upload-to-s3: - needs: [ b_windows, b_macos, b_linux, b_ems ] + needs: [ b_windows, b_macos, b_linux, b_linux_arm, b_ems ] runs-on: [ self-hosted, macOS ] @@ -174,6 +208,12 @@ jobs: path: github/solc-static-linux key: solc-linux-${{ github.run_id }} + - name: Restore solc-linux-arm + uses: actions/cache/restore@v5 + with: + path: github/solc-static-linux-arm + key: solc-linux-arm-${{ github.run_id }} + - name: Restore solc-ems uses: actions/cache/restore@v5 with: @@ -196,12 +236,13 @@ jobs: sed -En 's/^Version: ([0-9.]+.*\+commit\.[0-9a-f]+(\.mod)?).*$/\1/p' ) - mkdir -p solc-bin/{linux-amd64,macosx-amd64,windows-amd64,bin} + mkdir -p solc-bin/{linux-amd64,linux-arm64,macosx-amd64,windows-amd64,bin} - cp github/solc-static-linux "solc-bin/linux-amd64/solc-linux-amd64-v${full_version}" - cp github/solc-macos "solc-bin/macosx-amd64/solc-macosx-amd64-v${full_version}" - cp github/solc-windows.exe "solc-bin/windows-amd64/solc-windows-amd64-v${full_version}.exe" - cp github/soljson.js "solc-bin/bin/soljson-v${full_version}.js" + cp github/solc-static-linux-arm "solc-bin/linux-arm64/solc-linux-arm64-v${full_version}" + cp github/solc-static-linux "solc-bin/linux-amd64/solc-linux-amd64-v${full_version}" + cp github/solc-macos "solc-bin/macosx-amd64/solc-macosx-amd64-v${full_version}" + cp github/solc-windows.exe "solc-bin/windows-amd64/solc-windows-amd64-v${full_version}.exe" + cp github/soljson.js "solc-bin/bin/soljson-v${full_version}.js" cd solc-bin/ tar --create --file ../solc-bin-binaries.tar * @@ -224,6 +265,7 @@ jobs: aws s3 cp solc-windows.exe "s3://${bucket}/${{ github.sha }}/" --only-show-errors aws s3 cp solc-macos "s3://${bucket}/${{ github.sha }}/" --only-show-errors aws s3 cp solc-static-linux "s3://${bucket}/${{ github.sha }}/" --only-show-errors + aws s3 cp solc-static-linux-arm "s3://${bucket}/${{ github.sha }}/" --only-show-errors aws s3 cp soljson.js "s3://${bucket}/${{ github.sha }}/" --only-show-errors cd .. && rm -rf github solc-bin *.tar From 121a4b726d23eb9170699af2ee760ea62cd9c1b3 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 21 Jul 2026 18:08:15 +0800 Subject: [PATCH 100/121] ci: build release compiler targets only --- .github/workflows/build.sh | 4 ++-- .github/workflows/build_win.ps1 | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.sh b/.github/workflows/build.sh index fd0a79906b1a..e559451f3a71 100755 --- a/.github/workflows/build.sh +++ b/.github/workflows/build.sh @@ -14,6 +14,6 @@ mkdir -p build cd build # shellcheck disable=SC2086 -cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" $CMAKE_OPTIONS -G "Unix Makefiles" +cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" -DTESTS=OFF $CMAKE_OPTIONS -G "Unix Makefiles" -make +make solc diff --git a/.github/workflows/build_win.ps1 b/.github/workflows/build_win.ps1 index 8b9fcaa5d66c..431f347dc503 100644 --- a/.github/workflows/build_win.ps1 +++ b/.github/workflows/build_win.ps1 @@ -8,9 +8,7 @@ Write-Host "Building release version." mkdir build cd build $boost_dir=(Resolve-Path $PSScriptRoot\..\..\deps\boost\lib\cmake\Boost-*) -..\deps\cmake\bin\cmake -G "Visual Studio 17 2022" -DBoost_DIR="$boost_dir\" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_INSTALL_PREFIX="$PSScriptRoot\..\..\upload" -DUSE_Z3=OFF .. +..\deps\cmake\bin\cmake -G "Visual Studio 17 2022" -DBoost_DIR="$boost_dir\" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DUSE_Z3=OFF -DTESTS=OFF .. if ( -not $? ) { throw "CMake configure failed." } -msbuild solidity.sln /p:Configuration=Release /m:10 /v:minimal -if ( -not $? ) { throw "Build failed." } -..\deps\cmake\bin\cmake --build . -j 10 --target install --config Release -if ( -not $? ) { throw "Install target failed." } +..\deps\cmake\bin\cmake --build . -j 10 --target solc --config Release +if ( -not $? ) { throw "solc build failed." } From 4d99274b0ff3e6d1118639e3eb0c854955f604d9 Mon Sep 17 00:00:00 2001 From: Asuka Date: Wed, 22 Jul 2026 11:51:40 +0800 Subject: [PATCH 101/121] ci: migrate binary builds to GitHub-hosted runners --- .github/workflows/build.yml | 170 +++++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 59 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e5f7c4717077..eed1113383ef 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,22 +7,22 @@ on: jobs: b_windows: - runs-on: [ self-hosted, Windows ] + runs-on: windows-2022 steps: - name: Checkout code uses: actions/checkout@v5 - - - name: Fix git safe directory - run: git config --global --add safe.directory '*' + with: + submodules: true - name: Cache dependencies id: cache-deps uses: actions/cache@v5 with: - path: .\deps - key: dependencies-win-${{ runner.arch }}-${{ hashFiles('scripts/install_deps.ps1') }} - restore-keys: dependencies-win-${{ runner.arch }}- + path: | + .\deps\boost + .\deps\cmake + key: hosted-dependencies-win-v2-${{ runner.arch }}-${{ hashFiles('scripts/install_deps.ps1') }} - name: Installing dependencies if: steps.cache-deps.outputs.cache-hit != 'true' @@ -39,26 +39,68 @@ jobs: mkdir github/ cp build/solc/Release/solc.exe github/solc-windows.exe - - name: Save artifact to cache - uses: actions/cache/save@v5 + - name: Upload Windows binary + uses: actions/upload-artifact@v4 with: + name: solc-windows path: github/solc-windows.exe - key: solc-windows-${{ github.run_id }} - enableCrossOsArchive: true + if-no-files-found: error b_macos: - runs-on: [ self-hosted, macOS ] + runs-on: macos-15 env: CMAKE_BUILD_TYPE: Release - CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64 + CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64 -DBoost_ROOT=${{ github.workspace }}/deps/boost -DBoost_NO_SYSTEM_PATHS=ON TERM: xterm - MAKEFLAGS: -j5 - CPUs: 5 + MAKEFLAGS: -j 3 + CPUs: 3 steps: - name: Checkout code uses: actions/checkout@v5 + with: + submodules: true + + - name: Select pinned macOS toolchain + run: | + sudo xcode-select --switch /Applications/Xcode_16.4.app/Contents/Developer + bash .circleci/install_cmake.sh 3.29.3 + xcodebuild -version + clang --version + cmake --version + + - name: Cache universal Boost + id: cache-boost + uses: actions/cache@v5 + with: + path: deps/boost + key: hosted-boost-macos-universal-1.84.0-xcode16.4-v1 + + - name: Build universal Boost + if: steps.cache-boost.outputs.cache-hit != 'true' + run: | + boost_version=1.84.0 + boost_dir="boost_${boost_version//./_}" + boost_archive="${RUNNER_TEMP}/${boost_dir}.tar.bz2" + + curl --fail --location --retry 3 \ + "https://archives.boost.io/release/${boost_version}/source/${boost_dir}.tar.bz2" \ + --output "${boost_archive}" + tar -xjf "${boost_archive}" -C "${RUNNER_TEMP}" + + cd "${RUNNER_TEMP}/${boost_dir}" + ./bootstrap.sh \ + --with-toolset=clang \ + --with-libraries=filesystem,program_options,system,test + ./b2 -j 3 -d0 \ + link=static \ + variant=release \ + threading=multi \ + address-model=64 \ + architecture=arm+x86 \ + --prefix="${GITHUB_WORKSPACE}/deps/boost" \ + install - name: Run build script shell: bash -el {0} @@ -69,21 +111,21 @@ jobs: mkdir github/ cp build/solc/solc github/solc-macos - - name: Save artifact to cache - uses: actions/cache/save@v5 + - name: Upload macOS binary + uses: actions/upload-artifact@v4 with: + name: solc-macos path: github/solc-macos - key: solc-macos-${{ github.run_id }} - enableCrossOsArchive: true + if-no-files-found: error b_linux: - runs-on: [ self-hosted, Linux, for-linux ] + runs-on: ubuntu-24.04 env: CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DSOLC_LINK_STATIC=ON TERM: xterm - MAKEFLAGS: -j 10 - CPUs: 10 + MAKEFLAGS: -j 4 + CPUs: 4 container: # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404-6 @@ -92,6 +134,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v5 + with: + submodules: true - name: Fix git safe directory run: git config --global --add safe.directory '*' @@ -104,11 +148,12 @@ jobs: mkdir github/ cp build/solc/solc github/solc-static-linux - - name: Save artifact to cache - uses: actions/cache/save@v5 + - name: Upload Linux binary + uses: actions/upload-artifact@v4 with: + name: solc-linux path: github/solc-static-linux - key: solc-linux-${{ github.run_id }} + if-no-files-found: error b_linux_arm: runs-on: ubuntu-24.04-arm @@ -126,6 +171,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v5 + with: + submodules: true - name: Fix git safe directory run: git config --global --add safe.directory '*' @@ -138,19 +185,20 @@ jobs: mkdir github/ cp build/solc/solc github/solc-static-linux-arm - - name: Save artifact to cache - uses: actions/cache/save@v5 + - name: Upload Linux ARM64 binary + uses: actions/upload-artifact@v4 with: + name: solc-linux-arm path: github/solc-static-linux-arm - key: solc-linux-arm-${{ github.run_id }} + if-no-files-found: error b_ems: - runs-on: [ self-hosted, Linux, for-ems ] + runs-on: ubuntu-24.04 env: TERM: xterm - MAKEFLAGS: -j 10 - CPUs: 5 + MAKEFLAGS: -j 4 + CPUs: 4 container: # ghcr.io/argotorg/solidity-buildpack-deps:emscripten-21 @@ -160,6 +208,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v5 + with: + submodules: true - name: Fix git safe directory run: git config --global --add safe.directory '*' @@ -172,53 +222,55 @@ jobs: mkdir github/ cp upload/soljson.js github/soljson.js - - name: Save artifact to cache - uses: actions/cache/save@v5 + - name: Upload Emscripten binary + uses: actions/upload-artifact@v4 with: + name: solc-ems path: github/soljson.js - key: solc-ems-${{ github.run_id }} + if-no-files-found: error upload-to-s3: needs: [ b_windows, b_macos, b_linux, b_linux_arm, b_ems ] - runs-on: [ self-hosted, macOS ] + runs-on: [ self-hosted, Linux ] permissions: actions: read contents: read steps: - - name: Restore solc-windows - uses: actions/cache/restore@v5 + - name: Download solc-windows + uses: actions/download-artifact@v4 with: - path: github/solc-windows.exe - key: solc-windows-${{ github.run_id }} - enableCrossOsArchive: true + name: solc-windows + path: github - - name: Restore solc-macos - uses: actions/cache/restore@v5 + - name: Download solc-macos + uses: actions/download-artifact@v4 with: - path: github/solc-macos - key: solc-macos-${{ github.run_id }} - enableCrossOsArchive: true + name: solc-macos + path: github - - name: Restore solc-linux - uses: actions/cache/restore@v5 + - name: Download solc-linux + uses: actions/download-artifact@v4 with: - path: github/solc-static-linux - key: solc-linux-${{ github.run_id }} + name: solc-linux + path: github - - name: Restore solc-linux-arm - uses: actions/cache/restore@v5 + - name: Download solc-linux-arm + uses: actions/download-artifact@v4 with: - path: github/solc-static-linux-arm - key: solc-linux-arm-${{ github.run_id }} + name: solc-linux-arm + path: github - - name: Restore solc-ems - uses: actions/cache/restore@v5 + - name: Download solc-ems + uses: actions/download-artifact@v4 with: - path: github/soljson.js - key: solc-ems-${{ github.run_id }} + name: solc-ems + path: github + + - name: Restore executable permissions + run: chmod +x github/solc-static-linux github/solc-static-linux-arm github/solc-macos - name: List all artifacts run: | @@ -232,7 +284,7 @@ jobs: - name: Rename binaries to solc-bin naming convention run: | full_version=$( - github/solc-macos --version | + github/solc-static-linux --version | sed -En 's/^Version: ([0-9.]+.*\+commit\.[0-9a-f]+(\.mod)?).*$/\1/p' ) @@ -248,7 +300,7 @@ jobs: tar --create --file ../solc-bin-binaries.tar * - name: Upload to S3 - shell: zsh -el {0} + shell: bash env: S3_BUCKET_PROD: ${{ secrets.S3_BUCKET_PROD }} S3_BUCKET_TEST: ${{ secrets.S3_BUCKET_TEST }} From 470c8d5ba361f4a21afec6129005f764d0f4581a Mon Sep 17 00:00:00 2001 From: Asuka Date: Wed, 22 Jul 2026 13:30:29 +0800 Subject: [PATCH 102/121] ci: fix S3 artifact handoff --- .github/workflows/build.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eed1113383ef..10411607b4c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: cp build/solc/Release/solc.exe github/solc-windows.exe - name: Upload Windows binary - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: solc-windows path: github/solc-windows.exe @@ -112,7 +112,7 @@ jobs: cp build/solc/solc github/solc-macos - name: Upload macOS binary - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: solc-macos path: github/solc-macos @@ -149,7 +149,7 @@ jobs: cp build/solc/solc github/solc-static-linux - name: Upload Linux binary - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: solc-linux path: github/solc-static-linux @@ -186,7 +186,7 @@ jobs: cp build/solc/solc github/solc-static-linux-arm - name: Upload Linux ARM64 binary - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: solc-linux-arm path: github/solc-static-linux-arm @@ -223,7 +223,7 @@ jobs: cp upload/soljson.js github/soljson.js - name: Upload Emscripten binary - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: solc-ems path: github/soljson.js @@ -232,7 +232,7 @@ jobs: upload-to-s3: needs: [ b_windows, b_macos, b_linux, b_linux_arm, b_ems ] - runs-on: [ self-hosted, Linux ] + runs-on: [ self-hosted, Linux, for-linux ] permissions: actions: read @@ -240,31 +240,31 @@ jobs: steps: - name: Download solc-windows - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: solc-windows path: github - name: Download solc-macos - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: solc-macos path: github - name: Download solc-linux - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: solc-linux path: github - name: Download solc-linux-arm - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: solc-linux-arm path: github - name: Download solc-ems - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: solc-ems path: github From 8d58f5ab198503e1d0100711812437d9b0579c51 Mon Sep 17 00:00:00 2001 From: Asuka Date: Wed, 22 Jul 2026 15:34:12 +0800 Subject: [PATCH 103/121] ci: use production S3 bucket for uploads --- .github/workflows/build.yml | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 10411607b4c0..6ea100159faf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -302,22 +302,16 @@ jobs: - name: Upload to S3 shell: bash env: - S3_BUCKET_PROD: ${{ secrets.S3_BUCKET_PROD }} - S3_BUCKET_TEST: ${{ secrets.S3_BUCKET_TEST }} + S3_BUCKET: ${{ secrets.S3_BUCKET_PROD }} run: | - case "${GITHUB_REF_NAME}" in - develop) bucket="${S3_BUCKET_PROD}" ;; - release_*) bucket="${S3_BUCKET_TEST}" ;; - esac - - aws s3 cp github-binaries.tar "s3://${bucket}/${{ github.sha }}/" --only-show-errors - aws s3 cp solc-bin-binaries.tar "s3://${bucket}/${{ github.sha }}/" --only-show-errors + aws s3 cp github-binaries.tar "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors + aws s3 cp solc-bin-binaries.tar "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors cd github - aws s3 cp solc-windows.exe "s3://${bucket}/${{ github.sha }}/" --only-show-errors - aws s3 cp solc-macos "s3://${bucket}/${{ github.sha }}/" --only-show-errors - aws s3 cp solc-static-linux "s3://${bucket}/${{ github.sha }}/" --only-show-errors - aws s3 cp solc-static-linux-arm "s3://${bucket}/${{ github.sha }}/" --only-show-errors - aws s3 cp soljson.js "s3://${bucket}/${{ github.sha }}/" --only-show-errors + aws s3 cp solc-windows.exe "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors + aws s3 cp solc-macos "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors + aws s3 cp solc-static-linux "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors + aws s3 cp solc-static-linux-arm "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors + aws s3 cp soljson.js "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors cd .. && rm -rf github solc-bin *.tar From 086543227c7a72c80277ddd90e3d269b94caafeb Mon Sep 17 00:00:00 2001 From: Asuka Date: Fri, 24 Jul 2026 12:09:06 +0800 Subject: [PATCH 104/121] ci: isolate S3 upload workspace --- .github/workflows/build.yml | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6ea100159faf..3f3ca230a1f0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -239,49 +239,61 @@ jobs: contents: read steps: + - name: Prepare artifact workspace + id: artifact-workspace + shell: bash + run: | + artifact_work_dir="${RUNNER_TEMP}/solidity-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + mkdir -p "${artifact_work_dir}/github" + echo "path=${artifact_work_dir}" >> "${GITHUB_OUTPUT}" + - name: Download solc-windows uses: actions/download-artifact@v7 with: name: solc-windows - path: github + path: ${{ steps.artifact-workspace.outputs.path }}/github - name: Download solc-macos uses: actions/download-artifact@v7 with: name: solc-macos - path: github + path: ${{ steps.artifact-workspace.outputs.path }}/github - name: Download solc-linux uses: actions/download-artifact@v7 with: name: solc-linux - path: github + path: ${{ steps.artifact-workspace.outputs.path }}/github - name: Download solc-linux-arm uses: actions/download-artifact@v7 with: name: solc-linux-arm - path: github + path: ${{ steps.artifact-workspace.outputs.path }}/github - name: Download solc-ems uses: actions/download-artifact@v7 with: name: solc-ems - path: github + path: ${{ steps.artifact-workspace.outputs.path }}/github - name: Restore executable permissions + working-directory: ${{ steps.artifact-workspace.outputs.path }} run: chmod +x github/solc-static-linux github/solc-static-linux-arm github/solc-macos - name: List all artifacts + working-directory: ${{ steps.artifact-workspace.outputs.path }} run: | ls -R github/ - name: Create tarball for use on github + working-directory: ${{ steps.artifact-workspace.outputs.path }} run: | cd github tar --create --file ../github-binaries.tar * - name: Rename binaries to solc-bin naming convention + working-directory: ${{ steps.artifact-workspace.outputs.path }} run: | full_version=$( github/solc-static-linux --version | @@ -301,6 +313,7 @@ jobs: - name: Upload to S3 shell: bash + working-directory: ${{ steps.artifact-workspace.outputs.path }} env: S3_BUCKET: ${{ secrets.S3_BUCKET_PROD }} run: | @@ -313,5 +326,13 @@ jobs: aws s3 cp solc-static-linux "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors aws s3 cp solc-static-linux-arm "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors aws s3 cp soljson.js "s3://${S3_BUCKET}/${{ github.sha }}/" --only-show-errors - - cd .. && rm -rf github solc-bin *.tar + + - name: Clean artifact workspace + if: always() + shell: bash + env: + ARTIFACT_WORK_DIR: ${{ steps.artifact-workspace.outputs.path }} + run: | + if [[ -n "${ARTIFACT_WORK_DIR}" ]]; then + rm -rf -- "${ARTIFACT_WORK_DIR}" + fi From fd7601996c9f0edf8f90b518c88ebd3c7b41b8ec Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 10:52:08 +0800 Subject: [PATCH 105/121] fix(evmasm): align gas estimates with TVM pricing --- libevmasm/GasMeter.cpp | 24 ++++--- libevmasm/GasMeter.h | 12 ++++ test/libevmasm/GasMeter.cpp | 129 ++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 11 deletions(-) diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index 1f4a7ddb1844..8a18dc63e08a 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -71,13 +71,13 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ m_state->storageContent().count(slot) && classes.knownNonZero(m_state->storageContent().at(slot)) )) - gas = GasCosts::totalSstoreResetGas(m_evmVersion); //@todo take refunds into account + gas = GasCosts::tvmSstoreResetGas; //@todo take refunds into account else - gas = GasCosts::totalSstoreSetGas(m_evmVersion); + gas = GasCosts::tvmSstoreSetGas; break; } case Instruction::SLOAD: - gas = GasCosts::sloadGas(m_evmVersion); + gas = GasCosts::tvmSloadGas; break; case Instruction::RETURN: case Instruction::REVERT: @@ -122,13 +122,13 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ break; } case Instruction::EXTCODESIZE: - gas = GasCosts::extCodeGas(m_evmVersion); + gas = GasCosts::tvmExtCodeSizeGas; break; case Instruction::EXTCODEHASH: - gas = GasCosts::balanceGas(m_evmVersion); + gas = GasCosts::tvmExtCodeHashGas; break; case Instruction::EXTCODECOPY: - gas = GasCosts::extCodeGas(m_evmVersion); + gas = GasCosts::tvmExtCodeCopyGas; gas += memoryGas(-1, -3); gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-3)); break; @@ -157,18 +157,20 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ gas = GasConsumption::infinite(); else { - gas = GasCosts::callGas(m_evmVersion); + gas = GasCosts::tvmCallGas; if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(0))) gas += (*value); else gas = GasConsumption::infinite(); - if (_item.instruction() == Instruction::CALL || _item.instruction() == Instruction::CALLTOKEN) - gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists. int valueSize = 1; if (_item.instruction() == Instruction::DELEGATECALL || _item.instruction() == Instruction::STATICCALL) valueSize = 0; else if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize))) + { gas += GasCosts::callValueTransferGas; + if (_item.instruction() == Instruction::CALL || _item.instruction() == Instruction::CALLTOKEN) + gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists. + } int tokenIdSize = 0; if (_item.instruction() == Instruction::CALLTOKEN) tokenIdSize = 1; @@ -178,7 +180,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ break; } case Instruction::SELFDESTRUCT: - gas = GasCosts::selfdestructGas(m_evmVersion); + gas = GasCosts::tvmSelfdestructGas; gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists. break; case Instruction::CREATE: @@ -209,7 +211,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ case Instruction::BALANCE: case Instruction::TOKENBALANCE: case Instruction::ISCONTRACT: - gas = GasCosts::balanceGas(m_evmVersion); + gas = GasCosts::tvmBalanceGas; break; case Instruction::NATIVEFREEZE: gas = GasCosts::freezeV1Gas; diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index 7f2e4f6a3d00..69519cf0dff4 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -179,6 +179,18 @@ namespace GasCosts static unsigned const copyGas = 3; static unsigned const rjumpiGas = 4; + // TVM keeps fixed Energy prices for these instructions. Do not derive them + // from Ethereum hard-fork-dependent EVM prices when estimating TRON code. + static unsigned const tvmSloadGas = 50; + static unsigned const tvmSstoreSetGas = 20000; + static unsigned const tvmSstoreResetGas = 5000; + static unsigned const tvmBalanceGas = 20; + static unsigned const tvmExtCodeSizeGas = 20; + static unsigned const tvmExtCodeCopyGas = 20; + static unsigned const tvmExtCodeHashGas = 400; + static unsigned const tvmCallGas = 40; + static unsigned const tvmSelfdestructGas = 5000; + static unsigned const freezeV1Gas = 20000; static unsigned const expireTimeGas = 50; static unsigned const freezeV2Gas = 10000; diff --git a/test/libevmasm/GasMeter.cpp b/test/libevmasm/GasMeter.cpp index 6d82f86552ab..4ef73b455d8f 100644 --- a/test/libevmasm/GasMeter.cpp +++ b/test/libevmasm/GasMeter.cpp @@ -30,6 +30,9 @@ #include #include +#include +#include +#include using namespace solidity::evmasm; using namespace solidity::langutil; @@ -39,6 +42,26 @@ namespace solidity::frontend::test namespace { +GasMeter::GasConsumption estimateInstruction( + Instruction _instruction, + AssemblyItems _arguments, + bool _includeExternalCosts = true, + EVMVersion _evmVersion = EVMVersion{} +) +{ + _arguments.emplace_back(_instruction); + GasMeter meter(std::make_shared(), _evmVersion); + GasMeter::GasConsumption gas; + for (AssemblyItem const& item: _arguments) + gas = meter.estimateMax(item, _includeExternalCosts); + return gas; +} + +AssemblyItems zeroArguments(size_t _count) +{ + return AssemblyItems(_count, AssemblyItem{u256(0)}); +} + /// Feeds the four NATIVEVOTE arguments as constants (or CALLVALUE for an unknown /// element count) and returns the estimate for the NATIVEVOTE item itself. GasMeter::GasConsumption estimateVote( @@ -68,6 +91,112 @@ GasMeter::GasConsumption estimateVote( BOOST_AUTO_TEST_SUITE(EvmasmGasMeter) +BOOST_AUTO_TEST_CASE(tvm_fixed_instruction_prices_do_not_depend_on_evm_version) +{ + std::vector> const fixedCosts{ + {Instruction::SLOAD, 1, GasCosts::tvmSloadGas}, + {Instruction::BALANCE, 1, GasCosts::tvmBalanceGas}, + {Instruction::TOKENBALANCE, 2, GasCosts::tvmBalanceGas}, + {Instruction::ISCONTRACT, 1, GasCosts::tvmBalanceGas}, + {Instruction::EXTCODESIZE, 1, GasCosts::tvmExtCodeSizeGas}, + {Instruction::EXTCODECOPY, 4, GasCosts::tvmExtCodeCopyGas}, + {Instruction::EXTCODEHASH, 1, GasCosts::tvmExtCodeHashGas}, + {Instruction::NATIVEFREEZE, 3, GasCosts::freezeV1Gas + GasCosts::callNewAccountGas}, + {Instruction::NATIVEUNFREEZE, 2, GasCosts::freezeV1Gas}, + {Instruction::NATIVEFREEZEEXPIRETIME, 2, GasCosts::expireTimeGas}, + {Instruction::NATIVEWITHDRAWREWARD, 0, GasCosts::withdrawGas}, + {Instruction::NATIVEFREEZEBALANCEV2, 2, GasCosts::freezeV2Gas}, + {Instruction::NATIVEUNFREEZEBALANCEV2, 2, GasCosts::freezeV2Gas}, + {Instruction::NATIVECANCELALLUNFREEZEV2, 0, GasCosts::freezeV2Gas}, + {Instruction::NATIVEWITHDRAWEXPIREUNFREEZE, 0, GasCosts::freezeV2Gas}, + {Instruction::NATIVEDELEGATERESOURCE, 3, GasCosts::freezeV2Gas}, + {Instruction::NATIVEUNDELEGATERESOURCE, 3, GasCosts::freezeV2Gas} + }; + + for (EVMVersion const& evmVersion: EVMVersion::allVersions()) + for (auto const& [instruction, argumentCount, expected]: fixedCosts) + { + GasMeter::GasConsumption gas = estimateInstruction( + instruction, + zeroArguments(argumentCount), + true, + evmVersion + ); + BOOST_REQUIRE(!gas.isInfinite); + BOOST_CHECK_EQUAL(gas.value, u256(expected)); + } +} + +BOOST_AUTO_TEST_CASE(tvm_sstore_uses_java_tron_set_and_reset_prices) +{ + GasMeter::GasConsumption set = estimateInstruction(Instruction::SSTORE, {u256(1), u256(0)}); + BOOST_REQUIRE(!set.isInfinite); + BOOST_CHECK_EQUAL(set.value, u256(GasCosts::tvmSstoreSetGas)); + + GasMeter::GasConsumption reset = estimateInstruction(Instruction::SSTORE, {u256(0), u256(0)}); + BOOST_REQUIRE(!reset.isInfinite); + BOOST_CHECK_EQUAL(reset.value, u256(GasCosts::tvmSstoreResetGas)); +} + +BOOST_AUTO_TEST_CASE(tvm_call_family_uses_fixed_base_and_conditional_transfer_prices) +{ + for (Instruction instruction: {Instruction::DELEGATECALL, Instruction::STATICCALL}) + { + GasMeter::GasConsumption gas = estimateInstruction(instruction, zeroArguments(6), false); + BOOST_REQUIRE(!gas.isInfinite); + BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::tvmCallGas)); + } + + GasMeter::GasConsumption zeroValueCall = estimateInstruction( + Instruction::CALL, + {u256(0), u256(0), u256(0), u256(0), u256(0), u256(2), u256(0)}, + false + ); + BOOST_REQUIRE(!zeroValueCall.isInfinite); + BOOST_CHECK_EQUAL(zeroValueCall.value, u256(GasCosts::tvmCallGas)); + + GasMeter::GasConsumption valueCall = estimateInstruction( + Instruction::CALL, + {u256(0), u256(0), u256(0), u256(0), u256(1), u256(2), u256(0)}, + false + ); + BOOST_REQUIRE(!valueCall.isInfinite); + BOOST_CHECK_EQUAL( + valueCall.value, + u256(GasCosts::tvmCallGas + GasCosts::callValueTransferGas + GasCosts::callNewAccountGas) + ); + + GasMeter::GasConsumption valueCallCode = estimateInstruction( + Instruction::CALLCODE, + {u256(0), u256(0), u256(0), u256(0), u256(1), u256(2), u256(0)}, + false + ); + BOOST_REQUIRE(!valueCallCode.isInfinite); + BOOST_CHECK_EQUAL(valueCallCode.value, u256(GasCosts::tvmCallGas + GasCosts::callValueTransferGas)); +} + +BOOST_AUTO_TEST_CASE(tvm_calltoken_uses_fixed_base_and_conditional_transfer_prices) +{ + GasMeter::GasConsumption zeroValue = estimateInstruction( + Instruction::CALLTOKEN, + {u256(0), u256(0), u256(0), u256(0), u256(1), u256(0), u256(2), u256(0)}, + false + ); + BOOST_REQUIRE(!zeroValue.isInfinite); + BOOST_CHECK_EQUAL(zeroValue.value, u256(GasCosts::tvmCallGas)); + + GasMeter::GasConsumption nonZeroValue = estimateInstruction( + Instruction::CALLTOKEN, + {u256(0), u256(0), u256(0), u256(0), u256(1), u256(1), u256(2), u256(0)}, + false + ); + BOOST_REQUIRE(!nonZeroValue.isInfinite); + BOOST_CHECK_EQUAL( + nonZeroValue.value, + u256(GasCosts::tvmCallGas + GasCosts::callValueTransferGas + GasCosts::callNewAccountGas) + ); +} + BOOST_AUTO_TEST_CASE(nativevote_charges_memory_expansion_for_word_arrays) { // java-tron (EnergyCost.getVoteWitnessCost2/3) charges per array From 8e735509ec5a170e3ab54acc358b097126253bfa Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 12:09:48 +0800 Subject: [PATCH 106/121] fix(codegen): use TVM call price in gasNeededByCaller The pre-tangerine-whistle fallback paths in both code generators still derived the retained-gas amount from Ethereum fork-dependent GasCosts::callGas(). Switch them to the fixed TVM price for consistency with the GasMeter alignment. Also add GasMeter unit coverage for the SELFDESTRUCT estimate (tvmSelfdestructGas + callNewAccountGas). --- libsolidity/codegen/ExpressionCompiler.cpp | 2 +- libsolidity/codegen/ir/IRGeneratorForStatements.cpp | 6 +++--- test/libevmasm/GasMeter.cpp | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 475c4d32b8b0..eb0d7e410c30 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -3256,7 +3256,7 @@ void ExpressionCompiler::appendExternalFunctionCall( { // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. - u256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10; + u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10; if (_functionType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; if (!existenceChecked) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index e55282137185..ae1bc32c836e 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1760,7 +1760,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) { // @todo The value 10 is not exact and this could be fine-tuned, // but this has worked for years in the old code generator. - u256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10 + evmasm::GasCosts::callNewAccountGas; + u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10 + evmasm::GasCosts::callNewAccountGas; templ("gas", "sub(gas(), " + formatNumber(gasNeededByCaller) + ")"); } @@ -3189,7 +3189,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall( { // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. - u256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10; + u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10; if (funType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; if (!checkExtcodesize) @@ -3298,7 +3298,7 @@ void IRGeneratorForStatements::appendBareCall( { // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. - u256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10; + u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10; if (funType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; gasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know diff --git a/test/libevmasm/GasMeter.cpp b/test/libevmasm/GasMeter.cpp index 4ef73b455d8f..76765b4a6949 100644 --- a/test/libevmasm/GasMeter.cpp +++ b/test/libevmasm/GasMeter.cpp @@ -197,6 +197,16 @@ BOOST_AUTO_TEST_CASE(tvm_calltoken_uses_fixed_base_and_conditional_transfer_pric ); } +BOOST_AUTO_TEST_CASE(tvm_selfdestruct_uses_fixed_price_plus_new_account_cost) +{ + // java-tron (EnergyCost.getSuicideCost3) charges SUICIDE_V2 plus + // NEW_ACCT_CALL when the inheritor is a dead account. The estimator + // conservatively always adds the new-account cost. + GasMeter::GasConsumption gas = estimateInstruction(Instruction::SELFDESTRUCT, zeroArguments(1)); + BOOST_REQUIRE(!gas.isInfinite); + BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::tvmSelfdestructGas + GasCosts::callNewAccountGas)); +} + BOOST_AUTO_TEST_CASE(nativevote_charges_memory_expansion_for_word_arrays) { // java-tron (EnergyCost.getVoteWitnessCost2/3) charges per array From f8949f5250be5d4c8979e6005af15a7586c9e455 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 13:49:34 +0800 Subject: [PATCH 107/121] refactor(evmasm): clarify TVM gas constant names --- libevmasm/GasMeter.cpp | 30 +++++----- libevmasm/GasMeter.h | 28 +++++----- libsolidity/codegen/ExpressionCompiler.cpp | 2 +- .../codegen/ir/IRGeneratorForStatements.cpp | 6 +- test/libevmasm/GasMeter.cpp | 56 +++++++++---------- 5 files changed, 61 insertions(+), 61 deletions(-) diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index 8a18dc63e08a..e7e107fe1d31 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -71,13 +71,13 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ m_state->storageContent().count(slot) && classes.knownNonZero(m_state->storageContent().at(slot)) )) - gas = GasCosts::tvmSstoreResetGas; //@todo take refunds into account + gas = GasCosts::sstoreResetGasInTVM; //@todo take refunds into account else - gas = GasCosts::tvmSstoreSetGas; + gas = GasCosts::sstoreSetGasInTVM; break; } case Instruction::SLOAD: - gas = GasCosts::tvmSloadGas; + gas = GasCosts::sloadGasInTVM; break; case Instruction::RETURN: case Instruction::REVERT: @@ -122,13 +122,13 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ break; } case Instruction::EXTCODESIZE: - gas = GasCosts::tvmExtCodeSizeGas; + gas = GasCosts::extCodeSizeGasInTVM; break; case Instruction::EXTCODEHASH: - gas = GasCosts::tvmExtCodeHashGas; + gas = GasCosts::extCodeHashGasInTVM; break; case Instruction::EXTCODECOPY: - gas = GasCosts::tvmExtCodeCopyGas; + gas = GasCosts::extCodeCopyGasInTVM; gas += memoryGas(-1, -3); gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-3)); break; @@ -157,7 +157,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ gas = GasConsumption::infinite(); else { - gas = GasCosts::tvmCallGas; + gas = GasCosts::callGasInTVM; if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(0))) gas += (*value); else @@ -180,7 +180,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ break; } case Instruction::SELFDESTRUCT: - gas = GasCosts::tvmSelfdestructGas; + gas = GasCosts::selfdestructGasInTVM; gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists. break; case Instruction::CREATE: @@ -211,27 +211,27 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ case Instruction::BALANCE: case Instruction::TOKENBALANCE: case Instruction::ISCONTRACT: - gas = GasCosts::tvmBalanceGas; + gas = GasCosts::balanceGasInTVM; break; case Instruction::NATIVEFREEZE: - gas = GasCosts::freezeV1Gas; + gas = GasCosts::freezeV1GasInTVM; gas += GasCosts::callNewAccountGas; break; case Instruction::NATIVEUNFREEZE: - gas = GasCosts::freezeV1Gas; + gas = GasCosts::freezeV1GasInTVM; break; case Instruction::NATIVEFREEZEEXPIRETIME: - gas = GasCosts::expireTimeGas; + gas = GasCosts::freezeExpireTimeGasInTVM; break; case Instruction::NATIVEVOTE: - gas = GasCosts::voteGas; + gas = GasCosts::voteGasInTVM; // NATIVEVOTE reads two Solidity memory arrays. The stack length values are element // counts, not byte lengths, so include the array length slot and 32 bytes per element. gas += memoryGasForWordArray(-3, -2); gas += memoryGasForWordArray(-1, 0); break; case Instruction::NATIVEWITHDRAWREWARD: - gas = GasCosts::withdrawGas; + gas = GasCosts::withdrawRewardGasInTVM; break; case Instruction::NATIVEFREEZEBALANCEV2: case Instruction::NATIVEUNFREEZEBALANCEV2: @@ -239,7 +239,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ case Instruction::NATIVEWITHDRAWEXPIREUNFREEZE: case Instruction::NATIVEDELEGATERESOURCE: case Instruction::NATIVEUNDELEGATERESOURCE: - gas = GasCosts::freezeV2Gas; + gas = GasCosts::freezeV2GasInTVM; break; case Instruction::CHAINID: gas = runGas(Instruction::CHAINID, m_evmVersion); diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index 69519cf0dff4..06a4b8b609de 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -181,21 +181,21 @@ namespace GasCosts // TVM keeps fixed Energy prices for these instructions. Do not derive them // from Ethereum hard-fork-dependent EVM prices when estimating TRON code. - static unsigned const tvmSloadGas = 50; - static unsigned const tvmSstoreSetGas = 20000; - static unsigned const tvmSstoreResetGas = 5000; - static unsigned const tvmBalanceGas = 20; - static unsigned const tvmExtCodeSizeGas = 20; - static unsigned const tvmExtCodeCopyGas = 20; - static unsigned const tvmExtCodeHashGas = 400; - static unsigned const tvmCallGas = 40; - static unsigned const tvmSelfdestructGas = 5000; + static unsigned const sloadGasInTVM = 50; + static unsigned const sstoreSetGasInTVM = 20000; + static unsigned const sstoreResetGasInTVM = 5000; + static unsigned const balanceGasInTVM = 20; + static unsigned const extCodeSizeGasInTVM = 20; + static unsigned const extCodeCopyGasInTVM = 20; + static unsigned const extCodeHashGasInTVM = 400; + static unsigned const callGasInTVM = 40; + static unsigned const selfdestructGasInTVM = 5000; - static unsigned const freezeV1Gas = 20000; - static unsigned const expireTimeGas = 50; - static unsigned const freezeV2Gas = 10000; - static unsigned const withdrawGas = 20000; - static unsigned const voteGas = 30000; + static unsigned const freezeV1GasInTVM = 20000; + static unsigned const freezeExpireTimeGasInTVM = 50; + static unsigned const freezeV2GasInTVM = 10000; + static unsigned const withdrawRewardGasInTVM = 20000; + static unsigned const voteGasInTVM = 30000; } /** diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index eb0d7e410c30..768895a31f7c 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -3256,7 +3256,7 @@ void ExpressionCompiler::appendExternalFunctionCall( { // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. - u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10; + u256 gasNeededByCaller = evmasm::GasCosts::callGasInTVM + 10; if (_functionType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; if (!existenceChecked) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index ae1bc32c836e..9eb3f379378c 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1760,7 +1760,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) { // @todo The value 10 is not exact and this could be fine-tuned, // but this has worked for years in the old code generator. - u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10 + evmasm::GasCosts::callNewAccountGas; + u256 gasNeededByCaller = evmasm::GasCosts::callGasInTVM + 10 + evmasm::GasCosts::callNewAccountGas; templ("gas", "sub(gas(), " + formatNumber(gasNeededByCaller) + ")"); } @@ -3189,7 +3189,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall( { // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. - u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10; + u256 gasNeededByCaller = evmasm::GasCosts::callGasInTVM + 10; if (funType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; if (!checkExtcodesize) @@ -3298,7 +3298,7 @@ void IRGeneratorForStatements::appendBareCall( { // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. - u256 gasNeededByCaller = evmasm::GasCosts::tvmCallGas + 10; + u256 gasNeededByCaller = evmasm::GasCosts::callGasInTVM + 10; if (funType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; gasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know diff --git a/test/libevmasm/GasMeter.cpp b/test/libevmasm/GasMeter.cpp index 76765b4a6949..aeac86a2931e 100644 --- a/test/libevmasm/GasMeter.cpp +++ b/test/libevmasm/GasMeter.cpp @@ -94,23 +94,23 @@ BOOST_AUTO_TEST_SUITE(EvmasmGasMeter) BOOST_AUTO_TEST_CASE(tvm_fixed_instruction_prices_do_not_depend_on_evm_version) { std::vector> const fixedCosts{ - {Instruction::SLOAD, 1, GasCosts::tvmSloadGas}, - {Instruction::BALANCE, 1, GasCosts::tvmBalanceGas}, - {Instruction::TOKENBALANCE, 2, GasCosts::tvmBalanceGas}, - {Instruction::ISCONTRACT, 1, GasCosts::tvmBalanceGas}, - {Instruction::EXTCODESIZE, 1, GasCosts::tvmExtCodeSizeGas}, - {Instruction::EXTCODECOPY, 4, GasCosts::tvmExtCodeCopyGas}, - {Instruction::EXTCODEHASH, 1, GasCosts::tvmExtCodeHashGas}, - {Instruction::NATIVEFREEZE, 3, GasCosts::freezeV1Gas + GasCosts::callNewAccountGas}, - {Instruction::NATIVEUNFREEZE, 2, GasCosts::freezeV1Gas}, - {Instruction::NATIVEFREEZEEXPIRETIME, 2, GasCosts::expireTimeGas}, - {Instruction::NATIVEWITHDRAWREWARD, 0, GasCosts::withdrawGas}, - {Instruction::NATIVEFREEZEBALANCEV2, 2, GasCosts::freezeV2Gas}, - {Instruction::NATIVEUNFREEZEBALANCEV2, 2, GasCosts::freezeV2Gas}, - {Instruction::NATIVECANCELALLUNFREEZEV2, 0, GasCosts::freezeV2Gas}, - {Instruction::NATIVEWITHDRAWEXPIREUNFREEZE, 0, GasCosts::freezeV2Gas}, - {Instruction::NATIVEDELEGATERESOURCE, 3, GasCosts::freezeV2Gas}, - {Instruction::NATIVEUNDELEGATERESOURCE, 3, GasCosts::freezeV2Gas} + {Instruction::SLOAD, 1, GasCosts::sloadGasInTVM}, + {Instruction::BALANCE, 1, GasCosts::balanceGasInTVM}, + {Instruction::TOKENBALANCE, 2, GasCosts::balanceGasInTVM}, + {Instruction::ISCONTRACT, 1, GasCosts::balanceGasInTVM}, + {Instruction::EXTCODESIZE, 1, GasCosts::extCodeSizeGasInTVM}, + {Instruction::EXTCODECOPY, 4, GasCosts::extCodeCopyGasInTVM}, + {Instruction::EXTCODEHASH, 1, GasCosts::extCodeHashGasInTVM}, + {Instruction::NATIVEFREEZE, 3, GasCosts::freezeV1GasInTVM + GasCosts::callNewAccountGas}, + {Instruction::NATIVEUNFREEZE, 2, GasCosts::freezeV1GasInTVM}, + {Instruction::NATIVEFREEZEEXPIRETIME, 2, GasCosts::freezeExpireTimeGasInTVM}, + {Instruction::NATIVEWITHDRAWREWARD, 0, GasCosts::withdrawRewardGasInTVM}, + {Instruction::NATIVEFREEZEBALANCEV2, 2, GasCosts::freezeV2GasInTVM}, + {Instruction::NATIVEUNFREEZEBALANCEV2, 2, GasCosts::freezeV2GasInTVM}, + {Instruction::NATIVECANCELALLUNFREEZEV2, 0, GasCosts::freezeV2GasInTVM}, + {Instruction::NATIVEWITHDRAWEXPIREUNFREEZE, 0, GasCosts::freezeV2GasInTVM}, + {Instruction::NATIVEDELEGATERESOURCE, 3, GasCosts::freezeV2GasInTVM}, + {Instruction::NATIVEUNDELEGATERESOURCE, 3, GasCosts::freezeV2GasInTVM} }; for (EVMVersion const& evmVersion: EVMVersion::allVersions()) @@ -131,11 +131,11 @@ BOOST_AUTO_TEST_CASE(tvm_sstore_uses_java_tron_set_and_reset_prices) { GasMeter::GasConsumption set = estimateInstruction(Instruction::SSTORE, {u256(1), u256(0)}); BOOST_REQUIRE(!set.isInfinite); - BOOST_CHECK_EQUAL(set.value, u256(GasCosts::tvmSstoreSetGas)); + BOOST_CHECK_EQUAL(set.value, u256(GasCosts::sstoreSetGasInTVM)); GasMeter::GasConsumption reset = estimateInstruction(Instruction::SSTORE, {u256(0), u256(0)}); BOOST_REQUIRE(!reset.isInfinite); - BOOST_CHECK_EQUAL(reset.value, u256(GasCosts::tvmSstoreResetGas)); + BOOST_CHECK_EQUAL(reset.value, u256(GasCosts::sstoreResetGasInTVM)); } BOOST_AUTO_TEST_CASE(tvm_call_family_uses_fixed_base_and_conditional_transfer_prices) @@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(tvm_call_family_uses_fixed_base_and_conditional_transfer_pr { GasMeter::GasConsumption gas = estimateInstruction(instruction, zeroArguments(6), false); BOOST_REQUIRE(!gas.isInfinite); - BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::tvmCallGas)); + BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::callGasInTVM)); } GasMeter::GasConsumption zeroValueCall = estimateInstruction( @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(tvm_call_family_uses_fixed_base_and_conditional_transfer_pr false ); BOOST_REQUIRE(!zeroValueCall.isInfinite); - BOOST_CHECK_EQUAL(zeroValueCall.value, u256(GasCosts::tvmCallGas)); + BOOST_CHECK_EQUAL(zeroValueCall.value, u256(GasCosts::callGasInTVM)); GasMeter::GasConsumption valueCall = estimateInstruction( Instruction::CALL, @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(tvm_call_family_uses_fixed_base_and_conditional_transfer_pr BOOST_REQUIRE(!valueCall.isInfinite); BOOST_CHECK_EQUAL( valueCall.value, - u256(GasCosts::tvmCallGas + GasCosts::callValueTransferGas + GasCosts::callNewAccountGas) + u256(GasCosts::callGasInTVM + GasCosts::callValueTransferGas + GasCosts::callNewAccountGas) ); GasMeter::GasConsumption valueCallCode = estimateInstruction( @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(tvm_call_family_uses_fixed_base_and_conditional_transfer_pr false ); BOOST_REQUIRE(!valueCallCode.isInfinite); - BOOST_CHECK_EQUAL(valueCallCode.value, u256(GasCosts::tvmCallGas + GasCosts::callValueTransferGas)); + BOOST_CHECK_EQUAL(valueCallCode.value, u256(GasCosts::callGasInTVM + GasCosts::callValueTransferGas)); } BOOST_AUTO_TEST_CASE(tvm_calltoken_uses_fixed_base_and_conditional_transfer_prices) @@ -183,7 +183,7 @@ BOOST_AUTO_TEST_CASE(tvm_calltoken_uses_fixed_base_and_conditional_transfer_pric false ); BOOST_REQUIRE(!zeroValue.isInfinite); - BOOST_CHECK_EQUAL(zeroValue.value, u256(GasCosts::tvmCallGas)); + BOOST_CHECK_EQUAL(zeroValue.value, u256(GasCosts::callGasInTVM)); GasMeter::GasConsumption nonZeroValue = estimateInstruction( Instruction::CALLTOKEN, @@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(tvm_calltoken_uses_fixed_base_and_conditional_transfer_pric BOOST_REQUIRE(!nonZeroValue.isInfinite); BOOST_CHECK_EQUAL( nonZeroValue.value, - u256(GasCosts::tvmCallGas + GasCosts::callValueTransferGas + GasCosts::callNewAccountGas) + u256(GasCosts::callGasInTVM + GasCosts::callValueTransferGas + GasCosts::callNewAccountGas) ); } @@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(tvm_selfdestruct_uses_fixed_price_plus_new_account_cost) // conservatively always adds the new-account cost. GasMeter::GasConsumption gas = estimateInstruction(Instruction::SELFDESTRUCT, zeroArguments(1)); BOOST_REQUIRE(!gas.isInfinite); - BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::tvmSelfdestructGas + GasCosts::callNewAccountGas)); + BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::selfdestructGasInTVM + GasCosts::callNewAccountGas)); } BOOST_AUTO_TEST_CASE(nativevote_charges_memory_expansion_for_word_arrays) @@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(nativevote_charges_memory_expansion_for_word_arrays) // i.e. 7 and 11 words: 3 * 11 = 33 on top of the flat vote cost. GasMeter::GasConsumption gas = estimateVote(u256(128), u256(2), u256(256), u256(2)); BOOST_REQUIRE(!gas.isInfinite); - BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::voteGas + 33)); + BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::voteGasInTVM + 33)); } BOOST_AUTO_TEST_CASE(nativevote_charges_length_slot_for_empty_arrays) @@ -224,7 +224,7 @@ BOOST_AUTO_TEST_CASE(nativevote_charges_length_slot_for_empty_arrays) // ends are 128+32 and 512+32 bytes, i.e. 5 and 17 words: 3 * 17 = 51. GasMeter::GasConsumption gas = estimateVote(u256(128), u256(0), u256(512), u256(0)); BOOST_REQUIRE(!gas.isInfinite); - BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::voteGas + 51)); + BOOST_CHECK_EQUAL(gas.value, u256(GasCosts::voteGasInTVM + 51)); } BOOST_AUTO_TEST_CASE(nativevote_with_unknown_element_count_is_unbounded) From 121cd1b1fe3d39c049854c19feedfbfebb53e172 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:02:37 +0800 Subject: [PATCH 108/121] fix: gate experimental and unsupported VM targets --- liblangutil/EVMVersion.cpp | 18 ++++++++ libsolidity/analysis/TypeChecker.cpp | 38 +++++++++++++++++ libsolidity/interface/StandardCompiler.cpp | 15 ++++++- test/CMakeLists.txt | 1 + .../input.json | 1 + .../input.json | 1 + .../standard_no_append_cbor/input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 12 ++++++ .../output.json | 16 ++++++++ .../standard_viair_requested/input.json | 3 +- .../standard_yul_cfg_json_export/input.json | 1 + test/liblangutil/EVMVersion.cpp | 41 +++++++++++++++++++ .../tron/precompiles_before_byzantium.sol | 11 +++++ 30 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 test/cmdlineTests/standard_viair_experimental_warning/input.json create mode 100644 test/cmdlineTests/standard_viair_experimental_warning/output.json create mode 100644 test/liblangutil/EVMVersion.cpp create mode 100644 test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 4fbfe8de41b0..dae910af38e7 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -61,6 +61,24 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::TSTORE: case Instruction::TLOAD: return supportsTransientStorage(); + // TRON-specific instructions are not part of the EOF instruction set. + case Instruction::CALLTOKEN: + case Instruction::TOKENBALANCE: + case Instruction::CALLTOKENVALUE: + case Instruction::CALLTOKENID: + case Instruction::ISCONTRACT: + case Instruction::NATIVEFREEZE: + case Instruction::NATIVEUNFREEZE: + case Instruction::NATIVEFREEZEEXPIRETIME: + case Instruction::NATIVEVOTE: + case Instruction::NATIVEWITHDRAWREWARD: + case Instruction::NATIVEFREEZEBALANCEV2: + case Instruction::NATIVEUNFREEZEBALANCEV2: + case Instruction::NATIVECANCELALLUNFREEZEV2: + case Instruction::NATIVEWITHDRAWEXPIREUNFREEZE: + case Instruction::NATIVEDELEGATERESOURCE: + case Instruction::NATIVEUNDELEGATERESOURCE: + return !_eofVersion.has_value(); // Instructions below are deprecated in EOF case Instruction::CALL: case Instruction::CALLCODE: diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 5c8c53613482..0ce058809cdd 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1999,6 +1999,38 @@ void TypeChecker::typeCheckFunctionCall( "\"staticcall\" is not supported by the VM version." ); + static std::set const tronStaticCallKinds = { + FunctionType::Kind::ValidateMultiSign, + FunctionType::Kind::BatchValidateSign, + FunctionType::Kind::VerifyBurnProof, + FunctionType::Kind::VerifyTransferProof, + FunctionType::Kind::VerifyMintProof, + FunctionType::Kind::PedersenHash, + FunctionType::Kind::RewardBalance, + FunctionType::Kind::IsSrCandidate, + FunctionType::Kind::VoteCount, + FunctionType::Kind::UsedVoteCount, + FunctionType::Kind::ReceivedVoteCount, + FunctionType::Kind::TotalVoteCount, + FunctionType::Kind::GetChainParameter, + FunctionType::Kind::AvailableUnfreezeV2Size, + FunctionType::Kind::UnfreezableBalanceV2, + FunctionType::Kind::ExpireUnfreezeBalanceV2, + FunctionType::Kind::DelegatableResource, + FunctionType::Kind::ResourceV2, + FunctionType::Kind::CheckUnDelegateResource, + FunctionType::Kind::ResourceUsage, + FunctionType::Kind::TotalResource, + FunctionType::Kind::TotalDelegatedResource, + FunctionType::Kind::TotalAcquiredResource, + }; + if (!m_evmVersion.hasStaticCall() && tronStaticCallKinds.count(_functionType->kind())) + m_errorReporter.typeError( + 9137_error, + _functionCall.location(), + "This TRON builtin requires a Byzantium-compatible VM." + ); + // Perform standard function call type checking typeCheckFunctionGeneralChecks(_functionCall, _functionType); } @@ -3290,6 +3322,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) { if (magicType->kind() == MagicType::Kind::ABI) annotation.isPure = true; + else if (magicType->kind() == MagicType::Kind::Chain && !m_evmVersion.hasStaticCall()) + m_errorReporter.typeError( + 9137_error, + _memberAccess.location(), + "This TRON builtin requires a Byzantium-compatible VM." + ); else if (magicType->kind() == MagicType::Kind::MetaType && ( memberName == "creationCode" || memberName == "runtimeCode" )) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 85495a9e37e2..f5f737310c0d 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -430,7 +430,7 @@ std::optional checkAuxiliaryInputKeys(Json const& _input) std::optional checkSettingsKeys(Json const& _input) { - static std::set keys{"debug", "evmVersion", "eofVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; + static std::set keys{"debug", "evmVersion", "eofVersion", "experimentalViaIR", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; return checkKeys(_input, keys, "settings"); } @@ -820,6 +820,19 @@ std::variant StandardCompiler::parseI return formatFatalError(Error::Type::JSONError, "\"settings.viaIR\" must be a Boolean."); ret.viaIR = settings["viaIR"].get(); } + bool experimentalViaIRAcknowledged = false; + if (settings.contains("experimentalViaIR")) + { + if (!settings["experimentalViaIR"].is_boolean()) + return formatFatalError(Error::Type::JSONError, "\"settings.experimentalViaIR\" must be a Boolean."); + experimentalViaIRAcknowledged = settings["experimentalViaIR"].get(); + } + if (ret.viaIR && !experimentalViaIRAcknowledged) + ret.errors.emplace_back(formatError( + Error::Type::Warning, + "general", + "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning." + )); if (settings.contains("evmVersion")) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dbbcf3eaec81..8af881053fa6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,6 +63,7 @@ detect_stray_source_files("${libevmasm_sources}" "libevmasm/") set(liblangutil_sources liblangutil/CharStream.cpp + liblangutil/EVMVersion.cpp liblangutil/Scanner.cpp liblangutil/SourceLocation.cpp ) diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json index 6ff7662901e4..c306a4e01687 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json @@ -14,6 +14,7 @@ "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, "outputSelection": diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json index 06b89d0e01bf..d93f78f4d145 100644 --- a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json @@ -7,6 +7,7 @@ "outputSelection": {"*": {"*": ["ir"]}}, "optimizer": {"enabled": true}, "viaIR": true, + "experimentalViaIR": true, "debug": {"debugInfo": []} } } diff --git a/test/cmdlineTests/standard_no_append_cbor/input.json b/test/cmdlineTests/standard_no_append_cbor/input.json index 493325506dda..8fefb3ee0f50 100644 --- a/test/cmdlineTests/standard_no_append_cbor/input.json +++ b/test/cmdlineTests/standard_no_append_cbor/input.json @@ -10,6 +10,7 @@ "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json index f12e45bf2fa9..a1652b5633d9 100644 --- a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json +++ b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json @@ -10,6 +10,7 @@ "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json index 422a54f90d9f..aff5263670d6 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json index 8f8edcd29203..8fac23d615d9 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json index 8ed44ca05de2..15d1cd6ace39 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json index 27c400f9e946..add6ead1e0a0 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json index ad74649f5d1d..9394bea47fc3 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json index ad74649f5d1d..9394bea47fc3 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json index 35c8f940e82d..9a0d64f088a5 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json index e4681967f7db..028e195d408c 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json index 6239a7275e4d..4df522786b38 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json index fdb6c95b813e..1929a6a97ccd 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json index 5bc9d5467345..279c7ef44848 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json index 8952a241f6e7..e87a97e5bb08 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json index a684e0dc073b..641dcfb1827e 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json index 1f09e3a70253..c743d1609f2c 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json index dc86ac68494e..d2490aef88f6 100644 --- a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json @@ -5,6 +5,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json index dc86ac68494e..d2490aef88f6 100644 --- a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json @@ -5,6 +5,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_viair_experimental_warning/input.json b/test/cmdlineTests/standard_viair_experimental_warning/input.json new file mode 100644 index 000000000000..0b05d0d0e7cd --- /dev/null +++ b/test/cmdlineTests/standard_viair_experimental_warning/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "A.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.0; contract A {}" + } + }, + "settings": { + "viaIR": true, + "outputSelection": {} + } +} diff --git a/test/cmdlineTests/standard_viair_experimental_warning/output.json b/test/cmdlineTests/standard_viair_experimental_warning/output.json new file mode 100644 index 000000000000..c74bd9d6b3a5 --- /dev/null +++ b/test/cmdlineTests/standard_viair_experimental_warning/output.json @@ -0,0 +1,16 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", + "message": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", + "severity": "warning", + "type": "Warning" + } + ], + "sources": { + "A.sol": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_viair_requested/input.json b/test/cmdlineTests/standard_viair_requested/input.json index 76ae807a615c..542b0372d6b0 100644 --- a/test/cmdlineTests/standard_viair_requested/input.json +++ b/test/cmdlineTests/standard_viair_requested/input.json @@ -16,6 +16,7 @@ { "*": { "*": ["ir", "evm.bytecode.object", "evm.bytecode.generatedSources", "evm.deployedBytecode.object"] } }, - "viaIR": true + "viaIR": true, + "experimentalViaIR": true } } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/input.json b/test/cmdlineTests/standard_yul_cfg_json_export/input.json index b5353721ee09..545bf50ae705 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/input.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/input.json @@ -8,6 +8,7 @@ "enabled": true }, "viaIR": true, + "experimentalViaIR": true, "outputSelection": {"*": {"*": ["yulCFGJson"]}} } } diff --git a/test/liblangutil/EVMVersion.cpp b/test/liblangutil/EVMVersion.cpp new file mode 100644 index 000000000000..930ed4caaceb --- /dev/null +++ b/test/liblangutil/EVMVersion.cpp @@ -0,0 +1,41 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include +#include + +#include + +namespace solidity::langutil::test +{ + +BOOST_AUTO_TEST_SUITE(EVMVersionTest) + +BOOST_AUTO_TEST_CASE(tron_instructions_are_not_available_in_eof) +{ + for (unsigned opcode = 0xd0; opcode <= 0xdf; ++opcode) + { + auto const instruction = static_cast(opcode); + BOOST_TEST(EVMVersion::osaka().hasOpcode(instruction, std::nullopt)); + BOOST_TEST(!EVMVersion::osaka().hasOpcode(instruction, 1)); + } +} + +BOOST_AUTO_TEST_SUITE_END() + +} diff --git a/test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol b/test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol new file mode 100644 index 000000000000..34b9a3b1587f --- /dev/null +++ b/test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol @@ -0,0 +1,11 @@ +contract C { + function f() public view returns (bool, uint64) { + bool valid = validatemultisign(address(0), 0, bytes32(0), new bytes[](0)); + return (valid, chain.totalNetLimit); + } +} +// ==== +// EVMVersion: Date: Tue, 28 Jul 2026 11:06:03 +0800 Subject: [PATCH 109/121] fix: align TRON builtin semantics across backends --- libsolidity/analysis/GlobalContext.cpp | 2 +- libsolidity/ast/Types.cpp | 1 - libsolidity/codegen/ExpressionCompiler.cpp | 1 + .../codegen/ir/IRGeneratorForStatements.cpp | 35 ++++++++++++------ test/libsolidity/StandardCompiler.cpp | 36 +++++++++++++++++++ .../tron/validatemultisign_mutability.sol | 7 ++++ 6 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index c186ad1a0f1b..b9666889cfeb 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -379,7 +379,7 @@ void GlobalContext::addValidateMultiSignMethod() { parameterNames, returnParameterNames, FunctionType::Kind::ValidateMultiSign, - StateMutability::Pure, + StateMutability::View, nullptr) )); } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 46086f8f5d62..13fb93c3463b 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3875,7 +3875,6 @@ bool FunctionType::isPure() const return m_kind == Kind::KECCAK256 || m_kind == Kind::ECRecover || - m_kind == Kind::ValidateMultiSign || m_kind == Kind::BatchValidateSign || m_kind == Kind::VerifyBurnProof || m_kind == Kind::VerifyTransferProof || diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 768895a31f7c..0704d83e240a 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -3319,6 +3319,7 @@ void ExpressionCompiler::appendExternalFunctionCall( switch v case 0 { v := 0x60 } default { + if mod(returndatasize(), 0x20) { revert(0, 0) } v := mload(0x40) mstore(0x40, add(v, and(add(returndatasize(), 0x3f), not(0x1f)))) mstore(v, div(returndatasize(), 0x20)) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 9eb3f379378c..862ff7c9f592 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1658,7 +1658,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) std::string tokenId{expressionAsType(*arguments[1], *(parameterTypes[1]))}; Whiskers templ(R"( if iszero(lt(0xf4240, )) { revert(0, 0) } - if iszero(gt(exp(2, 63), )) { revert(0, 0) } + if iszero(gt(0x8000000000000000, )) { revert(0, 0) } let := 0 if iszero() { := } let := calltoken(,
, , , 0, 0, 0, 0) @@ -1682,7 +1682,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) std::string tokenId{expressionAsType(*arguments[0], *(parameterTypes[0]))}; Whiskers templ(R"( if iszero(lt(0xf4240, )) { revert(0, 0) } - if iszero(gt(exp(2, 63), )) { revert(0, 0) } + if iszero(gt(0x8000000000000000, )) { revert(0, 0) } let := tokenbalance(,
) )"); templ("address", address); @@ -2004,30 +2004,41 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) let := staticcall(gas(),
, , sub(, ), , ) if iszero() { () } + + if lt(returndatasize(), 0x20) { + mstore(, 0) + returndatacopy(, 0, returndatasize()) + } + - + + if mod(returndatasize(), 0x20) { revert(0, 0) } let := add(returndatasize(), 0x40) returndatacopy(add(, 0x40), 0, returndatasize()) mstore(, 0x20) mstore(add(, 0x20), div(returndatasize(), 0x20)) - + let := returndatasize() returndatacopy(, 0, ) - + let := - + if gt(, returndatasize()) { := returndatasize() } - + // update freeMemoryPointer according to dynamic return size (, ) - let := (, add(, )) + + let := mload() + + let := (, add(, )) + )"); templ("allocateUnbounded", m_utils.allocateUnboundedFunction()); templ("pos", m_context.newYulVariable()); @@ -2040,12 +2051,16 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) if (returnInfo.dynamicReturnSize) solAssert(m_context.evmVersion().supportsReturndata()); - templ("supportsReturnData", m_context.evmVersion().supportsReturndata()); + bool const isLegacyCompatibleMultisig = + functionType->kind() == FunctionType::Kind::ValidateMultiSign || + functionType->kind() == FunctionType::Kind::BatchValidateSign; + templ("isLegacyCompatibleMultisig", isLegacyCompatibleMultisig); + templ("strictReturnSize", m_context.evmVersion().supportsReturndata() && !isLegacyCompatibleMultisig); templ("returnDataSizeVar", m_context.newYulVariable()); templ("staticReturndataSize", std::to_string(returnInfo.estimatedReturnSize)); templ("isReturndataSizeDynamic", returnInfo.dynamicReturnSize); - templ("isMintProof",functionType->kind() == FunctionType::Kind::VerifyMintProof ||functionType->kind() == FunctionType::Kind::VerifyTransferProof); + templ("isProof", functionType->kind() == FunctionType::Kind::VerifyMintProof || functionType->kind() == FunctionType::Kind::VerifyTransferProof); templ("finalizeAllocation", m_utils.finalizeAllocationFunction()); templ("retVars", IRVariable(_functionCall).commaSeparatedList()); templ("abiDecode", m_context.abiFunctions().tupleDecoder(returnInfo.returnTypes, true)); diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 5360a2778677..60533522e36b 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -598,6 +598,42 @@ BOOST_AUTO_TEST_CASE(basic_compilation) ); } +BOOST_AUTO_TEST_CASE(tron_builtin_via_ir_codegen_guards) +{ + Json input = createLanguageAndSourcesSection("Solidity", {{"A.sol", R"( +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.30; +contract C { + function validate(address account, bytes32 content, bytes[] memory signatures) public view returns (bool) { + return validatemultisign(account, 0, content, signatures); + } + function transfer(address payable target, uint256 value, trcToken tokenId) public { + target.transferToken(value, tokenId); + } + function mint( + bytes32[9] memory output, + bytes32[2] memory bindingSignature, + uint64 value, + bytes32 signHash, + bytes32[33] memory frontier, + uint256 leafCount + ) public pure returns (bytes32[] memory) { + return verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); + } +} +)"}}); + input["settings"]["viaIR"] = true; + input["settings"]["outputSelection"]["*"]["*"] = Json::array({"ir"}); + + Json const output = compile(input.dump()); + BOOST_REQUIRE(containsAtMostWarnings(output)); + std::string const ir = output["contracts"]["A.sol"]["C"]["ir"].get(); + BOOST_TEST(ir.find("if iszero(gt(0x8000000000000000") != std::string::npos); + BOOST_TEST(ir.find("exp(2, 63)") == std::string::npos); + BOOST_TEST(ir.find("if lt(returndatasize(), 0x20)") != std::string::npos); + BOOST_TEST(ir.find("if mod(returndatasize(), 0x20) { revert(0, 0) }") != std::string::npos); +} + BOOST_AUTO_TEST_CASE(compilation_error) { char const* input = R"( diff --git a/test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol b/test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol new file mode 100644 index 000000000000..3be19672eb7d --- /dev/null +++ b/test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure returns (bool) { + return validatemultisign(address(0), 0, bytes32(0), new bytes[](0)); + } +} +// ---- +// TypeError 2527: (74-134): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". From 5ff386e2f5d91011a4cbacb7285335200a8e0a18 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:27:32 +0800 Subject: [PATCH 110/121] chore(codegen): assert TRON builtin arities --- libsolidity/codegen/ExpressionCompiler.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 0704d83e240a..92db9d9589d9 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1646,6 +1646,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; case FunctionType::Kind::Freeze: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1657,6 +1658,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::Unfreeze: { + solAssert(arguments.size() == 1 && function.parameterTypes().size() == 1, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i) { @@ -1669,6 +1671,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::FreezeExpireTime: { + solAssert(arguments.size() == 1 && function.parameterTypes().size() == 1, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i) { @@ -1679,6 +1682,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::Vote: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i) { @@ -1692,11 +1696,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::WithdrawReward: { + solAssert(arguments.empty() && function.parameterTypes().empty(), ""); m_context << Instruction::NATIVEWITHDRAWREWARD; break; } case FunctionType::Kind::FreezeBalanceV2: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1708,6 +1714,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::UnfreezeBalanceV2: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1719,16 +1726,19 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::CancelAllUnfreezeV2: { + solAssert(arguments.empty() && function.parameterTypes().empty(), ""); m_context << Instruction::NATIVECANCELALLUNFREEZEV2; break; } case FunctionType::Kind::WithdrawExpireUnfreeze: { + solAssert(arguments.empty() && function.parameterTypes().empty(), ""); m_context << Instruction::NATIVEWITHDRAWEXPIREUNFREEZE; break; } case FunctionType::Kind::DelegateResource: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1740,6 +1750,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::UnDelegateResource: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); From 447974f35c8f3ad1910ec3c2994e9cfbef0f67f8 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:14:36 +0800 Subject: [PATCH 111/121] fix(abi): restrict TRON address prefixes --- libsolidity/codegen/YulUtilFunctions.cpp | 4 +++- .../semanticTests/abiEncoderV2/cleanup/address.sol | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 4c3cd8c0fc69..97c4a0cda0c3 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -4056,7 +4056,9 @@ std::string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertO case Type::Category::Address: case Type::Category::Contract: { - templ("condition", "eq(value, " + cleanupFunction(IntegerType(168)) + "(value))"); + // Accept the canonical 20-byte form and TRON's 0x41-prefixed 21-byte form. + // Comparing all high bits at once also rejects values wider than 168 bits. + templ("condition", "or(iszero(div(value, 0x10000000000000000000000000000000000000000)), eq(div(value, 0x10000000000000000000000000000000000000000), 0x41))"); break; } case Type::Category::Integer: diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol index 44a462d1319b..48ad515e2184 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol @@ -21,6 +21,10 @@ contract C { // g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff // f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff // g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// f(uint256): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// g(address): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// f(uint256): 0x42abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// g(address): 0x42abcdef0123456789abcdef0123456789abcdefff -> FAILURE // f(uint256): 0x010000000000000000000000000000000000000000 -> 0 // g(address): 0x010000000000000000000000000000000000000000 -> FAILURE // f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff From 906913fb850fbf02ae4bd9843cf067d4705c8198 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:17:19 +0800 Subject: [PATCH 112/121] fix(smt): havoc TRON state effects conservatively --- libsolidity/formal/SMTEncoder.cpp | 62 +++++++++++++++++-- .../tron/state_mutation_havocs_balance.sol | 13 ++++ 2 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 95268032af0e..ad4120839a92 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -726,16 +726,66 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) " with the CHC engine." ); break; + case FunctionType::Kind::TransferToken: + case FunctionType::Kind::Freeze: + case FunctionType::Kind::Unfreeze: + case FunctionType::Kind::Vote: + case FunctionType::Kind::WithdrawReward: + case FunctionType::Kind::FreezeBalanceV2: + case FunctionType::Kind::UnfreezeBalanceV2: + case FunctionType::Kind::CancelAllUnfreezeV2: + case FunctionType::Kind::WithdrawExpireUnfreeze: + case FunctionType::Kind::DelegateResource: + case FunctionType::Kind::UnDelegateResource: + // These operations mutate TRON account or resource state. Since that state is + // not modeled explicitly, conservatively invalidate the symbolic blockchain + // state so balances and other observable state cannot remain falsely stable. + state().newState(); + m_unsupportedErrors.warning( + 4588_error, + _funCall.location(), + "Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively." + ); + break; + case FunctionType::Kind::TokenBalance: + case FunctionType::Kind::FreezeExpireTime: + case FunctionType::Kind::ValidateMultiSign: + case FunctionType::Kind::BatchValidateSign: + case FunctionType::Kind::VerifyBurnProof: + case FunctionType::Kind::VerifyTransferProof: + case FunctionType::Kind::VerifyMintProof: + case FunctionType::Kind::PedersenHash: + case FunctionType::Kind::RewardBalance: + case FunctionType::Kind::IsSrCandidate: + case FunctionType::Kind::VoteCount: + case FunctionType::Kind::UsedVoteCount: + case FunctionType::Kind::ReceivedVoteCount: + case FunctionType::Kind::TotalVoteCount: + case FunctionType::Kind::GetChainParameter: + case FunctionType::Kind::AvailableUnfreezeV2Size: + case FunctionType::Kind::UnfreezableBalanceV2: + case FunctionType::Kind::ExpireUnfreezeBalanceV2: + case FunctionType::Kind::DelegatableResource: + case FunctionType::Kind::ResourceV2: + case FunctionType::Kind::CheckUnDelegateResource: + case FunctionType::Kind::ResourceUsage: + case FunctionType::Kind::TotalResource: + case FunctionType::Kind::TotalDelegatedResource: + case FunctionType::Kind::TotalAcquiredResource: + // Keep unsupported TRON queries and precompiles unconstrained, while still + // applying the range/shape constraints of their Solidity return types. + if (!funType.returnParameterTypes().empty()) + setSymbolicUnknownValue(*m_context.expression(_funCall), m_context); + m_unsupportedErrors.warning( + 4588_error, + _funCall.location(), + "Assertion checker does not yet implement this type of function call." + ); + break; case FunctionType::Kind::DelegateCall: case FunctionType::Kind::BareCallCode: case FunctionType::Kind::BareDelegateCall: default: - // The TRON-specific builtins (freeze/unfreeze, vote, the various V2 calls, - // validatemultisign/batchvalidatesign, the zk-proof verifiers, pedersenhash, ...) - // are not modeled here: we only emit the warning below. Their state side effects - // are not havoc'd in this branch; soundness for state mutation across unmodeled - // calls is instead handled by the engine-level reset logic (CHC::unknownFunctionCall - // / makeOutsideFunctionCall and BMC's resetStateVariables paths). m_unsupportedErrors.warning( 4588_error, _funCall.location(), diff --git a/test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol b/test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol new file mode 100644 index 000000000000..e6ef09cdc08a --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol @@ -0,0 +1,13 @@ +contract C { + function f(uint256 amount) public { + uint256 balanceBefore = address(this).balance; + payable(address(this)).freeze(amount, 0); + assert(address(this).balance == balanceBefore); + } +} +// ==== +// SMTEngine: all +// SMTIgnoreCex: yes +// ---- +// Warning 4588: (116-156): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Warning 6328: (166-212): CHC: Assertion violation happens here. From c2bf7882c5ff27d3776fd1b90bddff5d48d265a3 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 15:03:23 +0800 Subject: [PATCH 113/121] fix: preserve TRON target compatibility --- liblangutil/EVMVersion.cpp | 18 -------- libsolidity/codegen/YulUtilFunctions.cpp | 4 +- test/CMakeLists.txt | 1 - test/liblangutil/EVMVersion.cpp | 41 ------------------- .../abiEncoderV2/cleanup/address.sol | 4 -- 5 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 test/liblangutil/EVMVersion.cpp diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index dae910af38e7..4fbfe8de41b0 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -61,24 +61,6 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::TSTORE: case Instruction::TLOAD: return supportsTransientStorage(); - // TRON-specific instructions are not part of the EOF instruction set. - case Instruction::CALLTOKEN: - case Instruction::TOKENBALANCE: - case Instruction::CALLTOKENVALUE: - case Instruction::CALLTOKENID: - case Instruction::ISCONTRACT: - case Instruction::NATIVEFREEZE: - case Instruction::NATIVEUNFREEZE: - case Instruction::NATIVEFREEZEEXPIRETIME: - case Instruction::NATIVEVOTE: - case Instruction::NATIVEWITHDRAWREWARD: - case Instruction::NATIVEFREEZEBALANCEV2: - case Instruction::NATIVEUNFREEZEBALANCEV2: - case Instruction::NATIVECANCELALLUNFREEZEV2: - case Instruction::NATIVEWITHDRAWEXPIREUNFREEZE: - case Instruction::NATIVEDELEGATERESOURCE: - case Instruction::NATIVEUNDELEGATERESOURCE: - return !_eofVersion.has_value(); // Instructions below are deprecated in EOF case Instruction::CALL: case Instruction::CALLCODE: diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 97c4a0cda0c3..4c3cd8c0fc69 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -4056,9 +4056,7 @@ std::string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertO case Type::Category::Address: case Type::Category::Contract: { - // Accept the canonical 20-byte form and TRON's 0x41-prefixed 21-byte form. - // Comparing all high bits at once also rejects values wider than 168 bits. - templ("condition", "or(iszero(div(value, 0x10000000000000000000000000000000000000000)), eq(div(value, 0x10000000000000000000000000000000000000000), 0x41))"); + templ("condition", "eq(value, " + cleanupFunction(IntegerType(168)) + "(value))"); break; } case Type::Category::Integer: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8af881053fa6..dbbcf3eaec81 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,7 +63,6 @@ detect_stray_source_files("${libevmasm_sources}" "libevmasm/") set(liblangutil_sources liblangutil/CharStream.cpp - liblangutil/EVMVersion.cpp liblangutil/Scanner.cpp liblangutil/SourceLocation.cpp ) diff --git a/test/liblangutil/EVMVersion.cpp b/test/liblangutil/EVMVersion.cpp deleted file mode 100644 index 930ed4caaceb..000000000000 --- a/test/liblangutil/EVMVersion.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include -#include - -#include - -namespace solidity::langutil::test -{ - -BOOST_AUTO_TEST_SUITE(EVMVersionTest) - -BOOST_AUTO_TEST_CASE(tron_instructions_are_not_available_in_eof) -{ - for (unsigned opcode = 0xd0; opcode <= 0xdf; ++opcode) - { - auto const instruction = static_cast(opcode); - BOOST_TEST(EVMVersion::osaka().hasOpcode(instruction, std::nullopt)); - BOOST_TEST(!EVMVersion::osaka().hasOpcode(instruction, 1)); - } -} - -BOOST_AUTO_TEST_SUITE_END() - -} diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol index 48ad515e2184..44a462d1319b 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol @@ -21,10 +21,6 @@ contract C { // g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff // f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff // g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff -// f(uint256): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff -// g(address): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff -// f(uint256): 0x42abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff -// g(address): 0x42abcdef0123456789abcdef0123456789abcdefff -> FAILURE // f(uint256): 0x010000000000000000000000000000000000000000 -> 0 // g(address): 0x010000000000000000000000000000000000000000 -> FAILURE // f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff From d18726334c034738899a3ba6a53fa85e7552b8bf Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 15:30:14 +0800 Subject: [PATCH 114/121] fix: keep Standard JSON viaIR behavior unchanged --- libsolidity/interface/StandardCompiler.cpp | 15 +-------------- .../input.json | 1 - .../input.json | 1 - .../standard_no_append_cbor/input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 12 ------------ .../output.json | 16 ---------------- .../standard_viair_requested/input.json | 3 +-- .../standard_yul_cfg_json_export/input.json | 1 - 25 files changed, 2 insertions(+), 65 deletions(-) delete mode 100644 test/cmdlineTests/standard_viair_experimental_warning/input.json delete mode 100644 test/cmdlineTests/standard_viair_experimental_warning/output.json diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index f5f737310c0d..85495a9e37e2 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -430,7 +430,7 @@ std::optional checkAuxiliaryInputKeys(Json const& _input) std::optional checkSettingsKeys(Json const& _input) { - static std::set keys{"debug", "evmVersion", "eofVersion", "experimentalViaIR", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; + static std::set keys{"debug", "evmVersion", "eofVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; return checkKeys(_input, keys, "settings"); } @@ -820,19 +820,6 @@ std::variant StandardCompiler::parseI return formatFatalError(Error::Type::JSONError, "\"settings.viaIR\" must be a Boolean."); ret.viaIR = settings["viaIR"].get(); } - bool experimentalViaIRAcknowledged = false; - if (settings.contains("experimentalViaIR")) - { - if (!settings["experimentalViaIR"].is_boolean()) - return formatFatalError(Error::Type::JSONError, "\"settings.experimentalViaIR\" must be a Boolean."); - experimentalViaIRAcknowledged = settings["experimentalViaIR"].get(); - } - if (ret.viaIR && !experimentalViaIRAcknowledged) - ret.errors.emplace_back(formatError( - Error::Type::Warning, - "general", - "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning." - )); if (settings.contains("evmVersion")) { diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json index c306a4e01687..6ff7662901e4 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json @@ -14,7 +14,6 @@ "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, "outputSelection": diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json index d93f78f4d145..06b89d0e01bf 100644 --- a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json @@ -7,7 +7,6 @@ "outputSelection": {"*": {"*": ["ir"]}}, "optimizer": {"enabled": true}, "viaIR": true, - "experimentalViaIR": true, "debug": {"debugInfo": []} } } diff --git a/test/cmdlineTests/standard_no_append_cbor/input.json b/test/cmdlineTests/standard_no_append_cbor/input.json index 8fefb3ee0f50..493325506dda 100644 --- a/test/cmdlineTests/standard_no_append_cbor/input.json +++ b/test/cmdlineTests/standard_no_append_cbor/input.json @@ -10,7 +10,6 @@ "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json index a1652b5633d9..f12e45bf2fa9 100644 --- a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json +++ b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json @@ -10,7 +10,6 @@ "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json index aff5263670d6..422a54f90d9f 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json index 8fac23d615d9..8f8edcd29203 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json index 15d1cd6ace39..8ed44ca05de2 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json index add6ead1e0a0..27c400f9e946 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json index 9394bea47fc3..ad74649f5d1d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json index 9394bea47fc3..ad74649f5d1d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json index 9a0d64f088a5..35c8f940e82d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json index 028e195d408c..e4681967f7db 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json index 4df522786b38..6239a7275e4d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json index 1929a6a97ccd..fdb6c95b813e 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json index 279c7ef44848..5bc9d5467345 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json index e87a97e5bb08..8952a241f6e7 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json index 641dcfb1827e..a684e0dc073b 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json index c743d1609f2c..1f09e3a70253 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json index d2490aef88f6..dc86ac68494e 100644 --- a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json @@ -5,7 +5,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json index d2490aef88f6..dc86ac68494e 100644 --- a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json @@ -5,7 +5,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_viair_experimental_warning/input.json b/test/cmdlineTests/standard_viair_experimental_warning/input.json deleted file mode 100644 index 0b05d0d0e7cd..000000000000 --- a/test/cmdlineTests/standard_viair_experimental_warning/input.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "A.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.0; contract A {}" - } - }, - "settings": { - "viaIR": true, - "outputSelection": {} - } -} diff --git a/test/cmdlineTests/standard_viair_experimental_warning/output.json b/test/cmdlineTests/standard_viair_experimental_warning/output.json deleted file mode 100644 index c74bd9d6b3a5..000000000000 --- a/test/cmdlineTests/standard_viair_experimental_warning/output.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "errors": [ - { - "component": "general", - "formattedMessage": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", - "message": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", - "severity": "warning", - "type": "Warning" - } - ], - "sources": { - "A.sol": { - "id": 0 - } - } -} diff --git a/test/cmdlineTests/standard_viair_requested/input.json b/test/cmdlineTests/standard_viair_requested/input.json index 542b0372d6b0..76ae807a615c 100644 --- a/test/cmdlineTests/standard_viair_requested/input.json +++ b/test/cmdlineTests/standard_viair_requested/input.json @@ -16,7 +16,6 @@ { "*": { "*": ["ir", "evm.bytecode.object", "evm.bytecode.generatedSources", "evm.deployedBytecode.object"] } }, - "viaIR": true, - "experimentalViaIR": true + "viaIR": true } } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/input.json b/test/cmdlineTests/standard_yul_cfg_json_export/input.json index 545bf50ae705..b5353721ee09 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/input.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/input.json @@ -8,7 +8,6 @@ "enabled": true }, "viaIR": true, - "experimentalViaIR": true, "outputSelection": {"*": {"*": ["yulCFGJson"]}} } } From 65b4dfd6ec8eb430992654e662b69b2912a54db3 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:18:48 +0800 Subject: [PATCH 115/121] fix: clarify TRON builtin parameter names --- libsolidity/analysis/GlobalContext.cpp | 16 ++++++++-------- .../syntaxTests/tron/builtin_named_arguments.sol | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 test/libsolidity/syntaxTests/tron/builtin_named_arguments.sol diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index b9666889cfeb..db9f8d6890a2 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -366,8 +366,8 @@ void GlobalContext::addValidateMultiSignMethod() { TypePointers returnParameterTypes; returnParameterTypes.push_back(TypeProvider::boolean()); strings parameterNames; - parameterNames.push_back("address"); - parameterNames.push_back("permissonid"); + parameterNames.push_back("account"); + parameterNames.push_back("permissionId"); parameterNames.push_back("content"); parameterNames.push_back("signatures"); strings returnParameterNames; @@ -436,7 +436,7 @@ void GlobalContext::addIsSRCandidateMethod() { TypePointers returnParameterTypes; returnParameterTypes.push_back(TypeProvider::boolean()); strings parameterNames; - parameterNames.push_back("address"); + parameterNames.push_back("srCandidate"); strings returnParameterNames; returnParameterNames.push_back("ok"); @@ -460,8 +460,8 @@ void GlobalContext::addVoteCountMethod() { TypePointers returnParameterTypes; returnParameterTypes.push_back(TypeProvider::uint256()); strings parameterNames; - parameterNames.push_back("address"); - parameterNames.push_back("address"); + parameterNames.push_back("voter"); + parameterNames.push_back("srCandidate"); strings returnParameterNames; returnParameterNames.push_back("result"); @@ -484,7 +484,7 @@ void GlobalContext::addTotalVoteCountMethod() { TypePointers returnParameterTypes; returnParameterTypes.push_back(TypeProvider::uint256()); strings parameterNames; - parameterNames.push_back("address"); + parameterNames.push_back("voter"); strings returnParameterNames; returnParameterNames.push_back("result"); @@ -507,7 +507,7 @@ void GlobalContext::addReceivedVoteCountMethod() { TypePointers returnParameterTypes; returnParameterTypes.push_back(TypeProvider::uint256()); strings parameterNames; - parameterNames.push_back("address"); + parameterNames.push_back("srCandidate"); strings returnParameterNames; returnParameterNames.push_back("result"); @@ -530,7 +530,7 @@ void GlobalContext::addUsedVoteCountMethod() { TypePointers returnParameterTypes; returnParameterTypes.push_back(TypeProvider::uint256()); strings parameterNames; - parameterNames.push_back("address"); + parameterNames.push_back("voter"); strings returnParameterNames; returnParameterNames.push_back("result"); diff --git a/test/libsolidity/syntaxTests/tron/builtin_named_arguments.sol b/test/libsolidity/syntaxTests/tron/builtin_named_arguments.sol new file mode 100644 index 000000000000..ed9021752450 --- /dev/null +++ b/test/libsolidity/syntaxTests/tron/builtin_named_arguments.sol @@ -0,0 +1,16 @@ +contract C { + function f(bytes[] memory signatures) public view { + validatemultisign({ + account: address(this), + permissionId: 0, + content: bytes32(0), + signatures: signatures + }); + isSrCandidate({srCandidate: address(this)}); + voteCount({voter: address(this), srCandidate: address(this)}); + totalVoteCount({voter: address(this)}); + receivedVoteCount({srCandidate: address(this)}); + usedVoteCount({voter: address(this)}); + } +} +// ---- From a29792517acca33faaa1fb08be8e46c6827129f3 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 10:55:07 +0800 Subject: [PATCH 116/121] fix: harden compiler and regression inputs --- libsolidity/interface/StandardCompiler.cpp | 2 ++ scripts/regressions.py | 29 +++++++++++++++---- scripts/splitSources.py | 17 +++++++++-- .../input.json | 13 +++++++++ .../output.json | 11 +++++++ 5 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 test/cmdlineTests/standard_wrong_type_bytecodeHash/input.json create mode 100644 test/cmdlineTests/standard_wrong_type_bytecodeHash/output.json diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 85495a9e37e2..fbb1a4c99868 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -513,6 +513,8 @@ std::optional checkMetadataKeys(Json const& _input) return formatFatalError(Error::Type::JSONError, "\"settings.metadata.appendCBOR\" must be Boolean"); if (_input.contains("useLiteralContent") && !_input["useLiteralContent"].is_boolean()) return formatFatalError(Error::Type::JSONError, "\"settings.metadata.useLiteralContent\" must be Boolean"); + if (_input.contains("bytecodeHash") && !_input["bytecodeHash"].is_string()) + return formatFatalError(Error::Type::JSONError, "\"settings.metadata.bytecodeHash\" must be a string"); static std::set hashes{"ipfs", "bzzr1", "none"}; if (_input.contains("bytecodeHash") && !hashes.count(_input["bytecodeHash"].get())) diff --git a/scripts/regressions.py b/scripts/regressions.py index e30c0aeb9f8d..8206b359c018 100755 --- a/scripts/regressions.py +++ b/scripts/regressions.py @@ -52,7 +52,7 @@ def parseCmdLine(cls, description, args): def run_cmd(command, logfile=None, env=None): """ Args: - command (str): command to run + command (list[str]): command and arguments to run logfile (str): log file name env (dict): dictionary holding key-value pairs for bash environment variables @@ -69,13 +69,33 @@ def run_cmd(command, logfile=None, env=None): env = os.environ.copy() with open(logfile, 'w', encoding='utf8') as logfh: - with subprocess.Popen(command, shell=True, executable='/bin/bash', - env=env, stdout=logfh, + with subprocess.Popen(command, env=env, stdout=logfh, stderr=subprocess.STDOUT) as proc: ret = proc.wait() logfh.close() return ret + @staticmethod + def run_corpus(fuzzer, corpus_dir, logfile, env=None): + if not env: + env = os.environ.copy() + + corpus_files = [] + for root, _, filenames in os.walk(corpus_dir): + corpus_files.extend(os.path.join(root, filename) for filename in filenames) + + with open(logfile, 'w', encoding='utf8') as logfh: + for corpus_file in sorted(corpus_files): + with subprocess.Popen( + [fuzzer, corpus_file], + env=env, + stdout=logfh, + stderr=subprocess.STDOUT + ) as proc: + if proc.wait() != 0: + return 255 + return 0 + def process_log(self, logfile): """ Args: @@ -106,8 +126,7 @@ def run(self): basename = os.path.basename(fuzzer) logfile = os.path.join(self._logpath, f"{basename}.log") corpus_dir = f"/tmp/solidity-fuzzing-corpus/{basename}_seed_corpus" - cmd = f"find {corpus_dir} -type f | xargs -n1 sh -c '{fuzzer} $0 || exit 255'" - self.run_cmd(cmd, logfile=logfile) + self.run_corpus(fuzzer, corpus_dir, logfile) ret = self.process_log(logfile) if not ret: print( diff --git a/scripts/splitSources.py b/scripts/splitSources.py index 5e783b2d5aa9..8607ee2d9cbf 100755 --- a/scripts/splitSources.py +++ b/scripts/splitSources.py @@ -10,8 +10,8 @@ # - 'false' if the file only had one source import sys -import os import traceback +from pathlib import Path def uncaught_exception_hook(exc_type, exc_value, exc_traceback): @@ -37,9 +37,20 @@ def writeSourceToFile(lines): filePath, srcName = extractSourceName(lines[0]) # print("sourceName is ", srcName) # print("filePath is", filePath) + outputRoot = Path.cwd().resolve() + sourcePath = Path(srcName) + if sourcePath.is_absolute(): + raise ValueError("Source name must be a relative path: " + srcName) + + outputPath = (outputRoot / sourcePath).resolve() + try: + outputPath.relative_to(outputRoot) + except ValueError: + raise ValueError("Source name escapes the output directory: " + srcName) + if filePath: - os.system("mkdir -p " + filePath) - with open(srcName, mode='a+', encoding='utf8', newline='') as f: + outputPath.parent.mkdir(parents=True, exist_ok=True) + with outputPath.open(mode='a+', encoding='utf8', newline='') as f: for idx, line in enumerate(lines[1:]): # write to file if line[:12] != "==== Source:": diff --git a/test/cmdlineTests/standard_wrong_type_bytecodeHash/input.json b/test/cmdlineTests/standard_wrong_type_bytecodeHash/input.json new file mode 100644 index 000000000000..565a94738c0a --- /dev/null +++ b/test/cmdlineTests/standard_wrong_type_bytecodeHash/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "A.sol": { + "content": "pragma solidity >=0.0; contract A {}" + } + }, + "settings": { + "metadata": { + "bytecodeHash": true + } + } +} diff --git a/test/cmdlineTests/standard_wrong_type_bytecodeHash/output.json b/test/cmdlineTests/standard_wrong_type_bytecodeHash/output.json new file mode 100644 index 000000000000..114c86e30f92 --- /dev/null +++ b/test/cmdlineTests/standard_wrong_type_bytecodeHash/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "\"settings.metadata.bytecodeHash\" must be a string", + "message": "\"settings.metadata.bytecodeHash\" must be a string", + "severity": "error", + "type": "JSONError" + } + ] +} From 8072fcfd264d61a8c9c3958af5e37d85b8c93b47 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 17:19:00 +0800 Subject: [PATCH 117/121] fix(lsp): avoid scanning the filesystem root --- libsolidity/lsp/LanguageServer.cpp | 18 ++++++++++++++++-- test/lsp.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/libsolidity/lsp/LanguageServer.cpp b/libsolidity/lsp/LanguageServer.cpp index d726139e3a73..d156b66422ac 100644 --- a/libsolidity/lsp/LanguageServer.cpp +++ b/libsolidity/lsp/LanguageServer.cpp @@ -59,6 +59,12 @@ namespace fs = boost::filesystem; namespace { +bool isFilesystemRoot(fs::path const& _path) +{ + auto const normalizedPath = _path.lexically_normal(); + return normalizedPath.has_root_path() && normalizedPath == normalizedPath.root_path(); +} + bool resolvesToRegularFile(boost::filesystem::path _path, int maxRecursionDepth = 10) { fs::file_status fileStatus = fs::status(_path); @@ -217,14 +223,20 @@ void LanguageServer::changeConfiguration(Json const& _settings) std::vector LanguageServer::allSolidityFilesFromProject() const { std::vector collectedPaths{}; + auto const basePath = m_fileRepository.basePath().lexically_normal(); + + // The filesystem root is used as a fallback when the client does not provide a workspace root. + // Keep full filesystem access available for explicit imports, but never scan the entire filesystem eagerly. + if (isFilesystemRoot(basePath)) + return collectedPaths; // We explicitly decided against including all files from include paths but leave the possibility // open for a future PR to enable such a feature to be optionally enabled (default disabled). // Note: Newer versions of boost have deprecated symlink_option::recurse #if (BOOST_VERSION < 107200) - auto directoryIterator = fs::recursive_directory_iterator(m_fileRepository.basePath(), fs::symlink_option::recurse); + auto directoryIterator = fs::recursive_directory_iterator(basePath, fs::symlink_option::recurse); #else - auto directoryIterator = fs::recursive_directory_iterator(m_fileRepository.basePath(), fs::directory_options::follow_directory_symlink); + auto directoryIterator = fs::recursive_directory_iterator(basePath, fs::directory_options::follow_directory_symlink); #endif for (fs::directory_entry const& dirEntry: directoryIterator) if ( @@ -412,6 +424,8 @@ void LanguageServer::handleInitialize(MessageID _id, Json const& _args) m_fileRepository = FileRepository(rootPath, {}); if (_args.contains("initializationOptions") && _args["initializationOptions"].is_object()) changeConfiguration(_args["initializationOptions"]); + if (m_fileLoadStrategy == FileLoadStrategy::ProjectDirectory && isFilesystemRoot(m_fileRepository.basePath())) + m_fileLoadStrategy = FileLoadStrategy::DirectlyOpenedAndOnImported; Json replyArgs; replyArgs["serverInfo"]["name"] = "solc"; diff --git a/test/lsp.py b/test/lsp.py index 11007ae822ec..16da8a25b1ac 100755 --- a/test/lsp.py +++ b/test/lsp.py @@ -1330,6 +1330,22 @@ def user_interaction_failed_autoupdate(self, test, sub_dir): # }}} # {{{ actual tests + def test_project_directory_without_workspace_root(self, solc: JsonRpcProcess) -> None: + """ + A missing workspace root falls back to the filesystem root internally. Project-directory + loading must not interpret that fallback as a request to scan the entire filesystem. + """ + self.setup_lsp( + solc, + expose_project_root=False, + file_load_strategy=FileLoadStrategy.ProjectDirectory + ) + TEST_NAME = 'publish_diagnostics_3' + published_diagnostics = self.open_file_and_wait_for_diagnostics(solc, TEST_NAME) + + self.expect_equal(len(published_diagnostics), 1, "Only the directly opened file is analyzed") + self.expect_equal(published_diagnostics[0]['uri'], self.get_test_file_uri(TEST_NAME), "Correct file URI") + def test_analyze_all_project_files_flat(self, solc: JsonRpcProcess) -> None: """ Tests the option (default) to analyze all .sol project files even when they have not been actively From 4b8114414a9c74b236e68e77fac2c574d84edccc Mon Sep 17 00:00:00 2001 From: Asuka Date: Wed, 29 Jul 2026 11:01:05 +0800 Subject: [PATCH 118/121] docs: fix bug metadata for TRON 0.8.30 security backports - Mark SOL-2025-1, SOL-2026-1, SOL-2026-2 and SOL-2026-3 as fixed in 0.8.30 on this release line: the fixes were backported from upstream 0.8.32/0.8.34/0.8.36, so the bug list must not claim 0.8.30 is still affected. - Restore TRON terminology (Trx) in legacy bug descriptions that were inadvertently overwritten with upstream wording (Ether) by the cherry-picks. - Regenerate docs/bugs_by_version.json from docs/bugs.json and this branch's Changelog.md; entries for versions not released on this branch (0.8.31+) drop out accordingly. --- docs/bugs.json | 18 +++++++-------- docs/bugs_by_version.json | 48 ++------------------------------------- 2 files changed, 11 insertions(+), 55 deletions(-) diff --git a/docs/bugs.json b/docs/bugs.json index 06a74c3b2835..1381139aa122 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -6,7 +6,7 @@ "description": "When the compiler detects that a custom layout specifier puts contract's static storage area too close to the end of the address space, it emits a warning. To make the warning more useful, the compiler tries to point at the last storage variable in that area. For this reason it walks the linearized inheritance hierarchy in reverse (from the least to the most derived). The list is calculated once and stored in an AST annotation called ``linearizedBaseContracts``. The direct cause of the bug was the fact that the code that reverses the list was doing it in place rather than on a copy, modifying the annotation. This effectively reversed the order of base contracts seen by any component that runs after layout checks: later phases of analysis, AST export, code generator, SMTChecker, etc. The observable effect was a reversed order of state variable initialization, constructor invocation, virtual function/modifier resolution, leading either to miscompilations or internal compiler errors, depending on the specific usage. Since the source of the bug was in the analysis stage, it was independent of the codegen pipeline or optimizer settings. The main condition necessary to trigger the bug was the presence of the warning in the output. The other is presence of language constructs whose evaluation depends on the inheritance order. While potential effects are very serious, this requirement excludes the vast majority of contracts as intentionally placing the storage variables in the last 2**64 slots is highly discouraged, which was actually the main reason for adding this warning.", "link": "https://blog.soliditylang.org/2026/07/09/inheritance-order-reversal-on-storage-end-warning-bug/", "introduced": "0.8.29", - "fixed": "0.8.36", + "fixed": "0.8.30", "severity": "medium" }, { @@ -16,7 +16,7 @@ "description": "To work around the 16-slot stack access limit of the EVM, the IR-based code generator can move local variables of stack-too-deep functions to fixed memory offsets. This relocation is unsound for recursive functions: a fixed offset would be shared by all activations of the function, so a recursive call would overwrite the caller's value. The stack limit evader therefore must not relocate variables of functions that are part of a recursive call chain. To this end, the call graph was searched for cycles using a path-based depth-first search that, once a function had been fully explored and popped from the search path, short-circuited on it on any later visit. As a result, a function shared between several intersecting cycles could be reached first through a path that did not yet close a cycle through it, get marked as finished, and then be skipped when a later path would have revealed that it does lie on a cycle. Such a function was misclassified as non-recursive. When a misclassified function was complex enough for the stack limit evader to relocate some of its variables, those variables were moved to fixed memory offsets and silently corrupted on recursion, producing wrong results rather than a compile-time error. Triggering the bug requires the IR pipeline, a set of mutually recursive functions whose call graph contains intersecting cycles, at least one of the functions in an undetected part of a cycle being complex enough to require relocation to memory, and an unfortunate processing order of the functions (which depends on the hashes of their Yul names). It is independent of whether the optimizer is enabled.", "link": "https://blog.soliditylang.org/2026/07/08/unsound-spill-in-mutual-recursion-bug/", "introduced": "0.7.2", - "fixed": "0.8.36", + "fixed": "0.8.30", "severity": "medium", "conditions": { "viaIR": true @@ -29,7 +29,7 @@ "description": "The IR-based code generator provides a set of Yul helper functions for basic operations, such as clearing, copying, encoding or type conversions. Not all functions are used by every contract. The codegen appends them to the generated sources individually, only when an operation that would invoke one of them is encountered. Utility functions are often specialized for different types and locations. Since Yul does not support generic functions, specialization is done by generating multiple versions of the same function, with the information distinguishing the variants embedded in their names. However, if not all the necessary bits of distinguishing information are properly accounted for, two helpers may end up with the same name, causing a collision. In this situation the codegen includes only one of them, with calls to both variants invoking it. This happened with the ``set_to_zero`` helper used when an area of transient or persistent storage needs to be cleared. The helper name was missing the location information, which resulted in a collision between the persistent and transient storage variants for the same type. This meant that contracts clearing both locations would actually clear only one, leaving the other untouched. Which location ended up being cleared depended on the order in which the code generator processed the input. The necessary condition to trigger the bug was the use of ``delete`` operator on a transient storage variable. This was due to value types being the only types supported in transient storage and ``delete`` being the only operation invoking the helper allowed on such types. The other necessary condition was clearing of persistent storage and in this case the range of affected operations was wider: operator ``delete``, array ``pop()`` or assignment that resulted in a longer array being overwritten with a shorter one. The cleared variable itself also did not necessarily have to be of the same type. It was enough that a matching value type was nested in it. It also did not always have to be the exact same value type - clearing operations on reference types are usually performed at slot granularity, treating every slot as ``uint256`` rather than clearing every value packed into it individually. To trigger the bug both operations had to be present within the same piece of bytecode. Independent contracts, not related through inheritance, would not affect each other this way. The presence of one operation only in creation code and the other only in deployed code would not trigger the bug either.", "link": "https://blog.soliditylang.org/2026/02/18/transient-storage-clearing-helper-collision-bug/", "introduced": "0.8.28", - "fixed": "0.8.34", + "fixed": "0.8.30", "severity": "high", "conditions": { "viaIR": true, @@ -43,7 +43,7 @@ "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", + "fixed": "0.8.30", "severity": "low" }, { @@ -523,7 +523,7 @@ "uid": "SOL-2017-5", "name": "ZeroFunctionSelector", "summary": "It is possible to craft the name of a function such that it is executed instead of the fallback function in very specific circumstances.", - "description": "If a function has a selector consisting only of zeros, is payable and part of a contract that does not have a fallback function and at most five external functions in total, this function is called instead of the fallback function if Ether is sent to the contract without data.", + "description": "If a function has a selector consisting only of zeros, is payable and part of a contract that does not have a fallback function and at most five external functions in total, this function is called instead of the fallback function if Trx is sent to the contract without data.", "fixed": "0.4.18", "severity": "very low" }, @@ -608,8 +608,8 @@ { "uid": "SOL-2016-7", "name": "LibrariesNotCallableFromPayableFunctions", - "summary": "Library functions threw an exception when called from a call that received Ether.", - "description": "Library functions are protected against sending them Ether through a call. Since the DELEGATECALL opcode forwards the information about how much Ether was sent with a call, the library function incorrectly assumed that Ether was sent to the library and threw an exception.", + "summary": "Library functions threw an exception when called from a call that received Trx.", + "description": "Library functions are protected against sending them Trx through a call. Since the DELEGATECALL opcode forwards the information about how much Trx was sent with a call, the library function incorrectly assumed that Trx was sent to the library and threw an exception.", "severity": "low", "introduced": "0.4.0", "fixed": "0.4.2" @@ -617,8 +617,8 @@ { "uid": "SOL-2016-6", "name": "SendFailsForZeroEther", - "summary": "The send function did not provide enough gas to the recipient if no Ether was sent with it.", - "description": "The recipient of an Ether transfer automatically receives a certain amount of gas from the EVM to handle the transfer. In the case of a zero-transfer, this gas is not provided which causes the recipient to throw an exception.", + "summary": "The send function did not provide enough gas to the recipient if no Trx was sent with it.", + "description": "The recipient of an Trx transfer automatically receives a certain amount of gas from the EVM to handle the transfer. In the case of a zero-transfer, this gas is not provided which causes the recipient to throw an exception.", "severity": "low", "fixed": "0.4.0" }, diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 0cc12bfe9eb7..25f987a2fc82 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -2070,53 +2070,9 @@ "released": "2021-03-23" }, "0.8.30": { - "bugs": [ - "InheritanceOrderReversalOnStorageEndWarning", - "UnsoundSpillInMutualRecursion", - "TransientStorageClearingHelperCollision", - "LostStorageArrayWriteOnSlotOverflow" - ], + "bugs": [], "released": "2025-05-07" }, - "0.8.31": { - "bugs": [ - "InheritanceOrderReversalOnStorageEndWarning", - "UnsoundSpillInMutualRecursion", - "TransientStorageClearingHelperCollision", - "LostStorageArrayWriteOnSlotOverflow" - ], - "released": "2025-12-03" - }, - "0.8.32": { - "bugs": [ - "InheritanceOrderReversalOnStorageEndWarning", - "UnsoundSpillInMutualRecursion", - "TransientStorageClearingHelperCollision" - ], - "released": "2025-12-18" - }, - "0.8.33": { - "bugs": [ - "InheritanceOrderReversalOnStorageEndWarning", - "UnsoundSpillInMutualRecursion", - "TransientStorageClearingHelperCollision" - ], - "released": "2025-12-18" - }, - "0.8.34": { - "bugs": [ - "InheritanceOrderReversalOnStorageEndWarning", - "UnsoundSpillInMutualRecursion" - ], - "released": "2026-02-18" - }, - "0.8.35": { - "bugs": [ - "InheritanceOrderReversalOnStorageEndWarning", - "UnsoundSpillInMutualRecursion" - ], - "released": "2026-04-29" - }, "0.8.4": { "bugs": [ "UnsoundSpillInMutualRecursion", @@ -2206,4 +2162,4 @@ ], "released": "2021-09-29" } -} +} \ No newline at end of file From 174578fe0c25cda0264e9429609162a732452939 Mon Sep 17 00:00:00 2001 From: Asuka Date: Wed, 29 Jul 2026 11:22:01 +0800 Subject: [PATCH 119/121] fix: reject Ethereum units in AST imports --- libsolidity/analysis/SyntaxChecker.cpp | 11 +++++ libsolidity/ast/ASTJsonImporter.cpp | 13 +++--- libsolidity/ast/Types.cpp | 13 +++--- libsolidity/interface/StandardCompiler.cpp | 10 +++++ test/libsolidity/SolidityTypes.cpp | 20 +++++++++ test/libsolidity/StandardCompiler.cpp | 50 ++++++++++++++++++++++ 6 files changed, 103 insertions(+), 14 deletions(-) diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 1e3f5f1c2a56..45920e63a91c 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -288,6 +288,17 @@ bool SyntaxChecker::visit(Literal const& _literal) if (_literal.token() != Token::Number) return true; + Token const subDenomination = static_cast(_literal.subDenomination()); + if (TokenTraits::isEtherSubdenomination(subDenomination)) + { + m_errorReporter.parserError( + 9999_error, + _literal.location(), + "Ether unit denomination is not supported by the compiler" + ); + return true; + } + ASTString const& value = _literal.value(); solAssert(!value.empty(), ""); diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 499b7df62a2a..7e61275aa1ea 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -1236,13 +1236,12 @@ Literal::SubDenomination ASTJsonImporter::subdenomination(Json const& _node) std::string const subDenStr = subDen.get(); - if (subDenStr == "wei") - return Literal::SubDenomination::Wei; - else if (subDenStr == "gwei") - return Literal::SubDenomination::Gwei; - else if (subDenStr == "ether") - return Literal::SubDenomination::Ether; - else if (subDenStr == "sun") + astAssert( + subDenStr != "wei" && subDenStr != "gwei" && subDenStr != "ether", + "Ether unit denomination is not supported by the compiler" + ); + + if (subDenStr == "sun") return Literal::SubDenomination::Sun; else if (subDenStr == "trx") return Literal::SubDenomination::Trx; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 13fb93c3463b..36b73ae98069 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1081,16 +1081,15 @@ std::tuple RationalNumberType::isValidLiteral(Literal const& _li } switch (_literal.subDenomination()) { - case Literal::SubDenomination::None: case Literal::SubDenomination::Wei: - case Literal::SubDenomination::Sun: - case Literal::SubDenomination::Second: - break; case Literal::SubDenomination::Gwei: - value *= bigint("1000000000"); - break; case Literal::SubDenomination::Ether: - value *= bigint("1000000000000000000"); + // These denominations are not part of the TRON language, even if a + // Literal is constructed without going through the parser or AST importer. + return std::make_tuple(false, rational(0)); + case Literal::SubDenomination::None: + case Literal::SubDenomination::Sun: + case Literal::SubDenomination::Second: break; case Literal::SubDenomination::Trx: value *= bigint("1000000"); diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index fbb1a4c99868..117dc0b1a07b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1385,6 +1385,16 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu if (binariesRequested) compilerStack.compile(); } + catch (InvalidAstError const& _exc) + { + errors.emplace_back(formatErrorWithException( + compilerStack, + _exc, + Error::Type::JSONError, + "general", + "Failed to import AST" + )); + } catch (util::Exception const& _exc) { solThrow(util::Exception, "Failed to import AST: "s + _exc.what()); diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp index e4523292f6da..6c3bdbe3c456 100644 --- a/test/libsolidity/SolidityTypes.cpp +++ b/test/libsolidity/SolidityTypes.cpp @@ -74,6 +74,26 @@ BOOST_AUTO_TEST_CASE(ufixed_types) } } +BOOST_AUTO_TEST_CASE(ethereum_subdenominations_are_invalid) +{ + int64_t id = 0; + for (Literal::SubDenomination subdenomination: { + Literal::SubDenomination::Wei, + Literal::SubDenomination::Gwei, + Literal::SubDenomination::Ether + }) + { + Literal literal( + ++id, + SourceLocation{}, + Token::Number, + std::make_shared("1"), + subdenomination + ); + BOOST_CHECK(TypeProvider::forLiteral(literal) == nullptr); + } +} + BOOST_AUTO_TEST_CASE(storage_layout_simple) { MemberList members(MemberList::MemberMap({ diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 60533522e36b..34b268b75616 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -1816,6 +1816,56 @@ BOOST_AUTO_TEST_CASE(stopAfter_ast_output) BOOST_CHECK(result["sources"]["a.sol"]["ast"].is_object()); } +BOOST_AUTO_TEST_CASE(solidity_ast_rejects_ethereum_subdenominations) +{ + frontend::StandardCompiler compiler; + Json sourceInput = createLanguageAndSourcesSection("Solidity", {{ + "A.sol", + "contract C { function f() public pure returns (uint256) { return 1 trx; } }" + }}); + sourceInput["settings"]["outputSelection"]["*"][""] = Json::array({"ast"}); + + Json sourceResult = compiler.compile(sourceInput); + BOOST_REQUIRE(containsAtMostWarnings(sourceResult)); + BOOST_REQUIRE(sourceResult["sources"]["A.sol"]["ast"].is_object()); + + for (std::string const& subdenomination: {"wei"s, "gwei"s, "ether"s}) + { + Json ast = sourceResult["sources"]["A.sol"]["ast"]; + bool literalFound = false; + auto replaceSubdenomination = [&](auto&& _replaceSubdenomination, Json& _node) -> void { + if (_node.is_object()) + { + if (_node.value("nodeType", "") == "Literal" && _node.value("subdenomination", "") == "trx") + { + _node["subdenomination"] = subdenomination; + literalFound = true; + } + for (Json& value: _node) + _replaceSubdenomination(_replaceSubdenomination, value); + } + else if (_node.is_array()) + for (Json& value: _node) + _replaceSubdenomination(_replaceSubdenomination, value); + }; + replaceSubdenomination(replaceSubdenomination, ast); + BOOST_REQUIRE(literalFound); + + Json astInput = Json::object(); + astInput["language"] = "SolidityAST"; + astInput["sources"]["A.sol"]["ast"] = std::move(ast); + astInput["settings"]["outputSelection"]["*"]["*"] = Json::array({"evm.bytecode.object"}); + + Json astResult = compiler.compile(astInput); + BOOST_CHECK(containsError( + astResult, + "JSONError", + "Failed to import AST: Ether unit denomination is not supported by the compiler" + )); + BOOST_CHECK(!astResult.contains("contracts")); + } +} + BOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract) { char const* input = R"( From 0d4fe485bda9c721e02727af22ca4cf5ee5247db Mon Sep 17 00:00:00 2001 From: Asuka Date: Thu, 30 Jul 2026 18:40:28 +0800 Subject: [PATCH 120/121] fix: harden SMT, JSON input, and TVM gas estimation --- libevmasm/ConstantOptimiser.cpp | 2 +- libevmasm/GasMeter.cpp | 94 ++++++---- libevmasm/GasMeter.h | 11 +- libsolidity/formal/Predicate.cpp | 7 +- libsolidity/formal/SMTEncoder.cpp | 4 +- libsolidity/formal/SymbolicState.cpp | 12 +- libsolidity/formal/SymbolicTypes.cpp | 7 + libsolidity/interface/StandardCompiler.cpp | 4 +- libyul/backends/evm/EVMMetrics.cpp | 2 +- test/libevmasm/GasMeter.cpp | 167 ++++++++++++++++++ test/libevmasm/Optimiser.cpp | 26 +++ test/libsolidity/StandardCompiler.cpp | 36 ++++ .../smtCheckerTests/tron/magic_members.sol | 39 ++++ .../tron/magic_members_bmc.sol | 39 ++++ .../tron/state_mutation_return_ranges.sol | 23 +++ .../tron/state_mutation_return_ranges_bmc.sol | 23 +++ test/libyul/Metrics.cpp | 21 +++ 17 files changed, 468 insertions(+), 49 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/tron/magic_members.sol create mode 100644 test/libsolidity/smtCheckerTests/tron/magic_members_bmc.sol create mode 100644 test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges.sol create mode 100644 test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges_bmc.sol diff --git a/libevmasm/ConstantOptimiser.cpp b/libevmasm/ConstantOptimiser.cpp index 7cf00fc9ed41..7298fe440008 100644 --- a/libevmasm/ConstantOptimiser.cpp +++ b/libevmasm/ConstantOptimiser.cpp @@ -383,7 +383,7 @@ bigint ComputeMethod::gasNeeded(AssemblyItems const& _routine) const { auto numExps = static_cast(count(_routine.begin(), _routine.end(), Instruction::EXP)); return combineGas( - simpleRunGas(_routine, m_params.evmVersion) + numExps * (GasCosts::expGas + GasCosts::expByteGas(m_params.evmVersion)), + simpleRunGas(_routine, m_params.evmVersion) + numExps * GasCosts::expByteGasInTVM, // Data gas for routine: Some bytes are zero, but we ignore them. bytesRequired(_routine, m_params.evmVersion) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas), 0 diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index e7e107fe1d31..6c2cfdb0ee11 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -20,6 +20,8 @@ #include +#include + using namespace solidity; using namespace solidity::util; using namespace solidity::evmasm; @@ -87,17 +89,11 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ case Instruction::MLOAD: case Instruction::MSTORE: gas = runGas(_item.instruction(), m_evmVersion); - gas += memoryGas(classes.find(Instruction::ADD, { - m_state->relativeStackElement(0), - classes.find(AssemblyItem(32)) - })); + gas += memoryGas(m_state->relativeStackElement(0), u256(32)); break; case Instruction::MSTORE8: gas = runGas(_item.instruction(), m_evmVersion); - gas += memoryGas(classes.find(Instruction::ADD, { - m_state->relativeStackElement(0), - classes.find(AssemblyItem(1)) - })); + gas += memoryGas(m_state->relativeStackElement(0), u256(1)); break; case Instruction::KECCAK256: gas = GasCosts::keccak256Gas; @@ -113,11 +109,18 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ break; case Instruction::MCOPY: { - GasConsumption memoryGasFromRead = memoryGas(-1, -2); - GasConsumption memoryGasFromWrite = memoryGas(0, -2); - gas = runGas(_item.instruction(), m_evmVersion); - gas += (memoryGasFromRead < memoryGasFromWrite ? memoryGasFromWrite : memoryGasFromRead); + ExpressionClasses::Id sizeExpression = m_state->relativeStackElement(-2); + if (!classes.knownZero(sizeExpression)) + { + u256 const* source = classes.knownConstant(m_state->relativeStackElement(-1)); + u256 const* destination = classes.knownConstant(m_state->relativeStackElement(0)); + u256 const* size = classes.knownConstant(sizeExpression); + if (!source || !destination || !size) + gas = GasConsumption::infinite(); + else + gas += memoryGas(bigint(std::max(*source, *destination)) + *size); + } gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2)); break; } @@ -192,6 +195,8 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ { gas = GasCosts::createGas; gas += memoryGas(-1, -2); + if (_item.instruction() == Instruction::CREATE2) + gas += wordGas(GasCosts::create2WordGasInTVM, m_state->relativeStackElement(-2)); } break; case Instruction::EXP: @@ -202,11 +207,11 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ { // Note: msb() counts from 0 and throws on 0 as input. unsigned const significantByteCount = (static_cast(boost::multiprecision::msb(*value)) + 1u + 7u) / 8u; - gas += GasCosts::expByteGas(m_evmVersion) * significantByteCount; + gas += GasCosts::expByteGasInTVM * significantByteCount; } } else - gas += GasCosts::expByteGas(m_evmVersion) * 32; + gas += GasCosts::expByteGasInTVM * 32; break; case Instruction::BALANCE: case Instruction::TOKENBALANCE: @@ -267,36 +272,53 @@ GasMeter::GasConsumption GasMeter::wordGas(u256 const& _multiplier, ExpressionCl u256 const* value = m_state->expressionClasses().knownConstant(_value); if (!value) return GasConsumption::infinite(); - return GasConsumption(_multiplier * ((*value + 31) / 32)); + bigint gas = bigint(_multiplier) * ((bigint(*value) + 31) / 32); + if (gas > std::numeric_limits::max()) + return GasConsumption::infinite(); + return GasConsumption(u256(gas)); } -GasMeter::GasConsumption GasMeter::memoryGas(ExpressionClasses::Id _position) +GasMeter::GasConsumption GasMeter::memoryGas(bigint const& _position) { - u256 const* value = m_state->expressionClasses().knownConstant(_position); - if (!value) + if ( + _position < 0 || + _position > GasCosts::memorySizeLimitInTVM || + bigint(m_largestMemoryAccess) > GasCosts::memorySizeLimitInTVM + ) return GasConsumption::infinite(); - if (*value < m_largestMemoryAccess) + u256 const value = u256(_position); + if (value < m_largestMemoryAccess) return GasConsumption(0); u256 previous = m_largestMemoryAccess; - m_largestMemoryAccess = *value; + m_largestMemoryAccess = value; auto memGas = [=](u256 const& pos) -> u256 { u256 size = (pos + 31) / 32; return GasCosts::memoryGas * size + size * size / GasCosts::quadCoeffDiv; }; - return memGas(*value) - memGas(previous); + return memGas(value) - memGas(previous); +} + +GasMeter::GasConsumption GasMeter::memoryGas(ExpressionClasses::Id _offset, u256 const& _size) +{ + u256 const* offset = m_state->expressionClasses().knownConstant(_offset); + if (!offset) + return GasConsumption::infinite(); + return memoryGas(bigint(*offset) + _size); } GasMeter::GasConsumption GasMeter::memoryGas(int _stackPosOffset, int _stackPosSize) { ExpressionClasses& classes = m_state->expressionClasses(); - if (classes.knownZero(m_state->relativeStackElement(_stackPosSize))) + ExpressionClasses::Id offsetExpression = m_state->relativeStackElement(_stackPosOffset); + ExpressionClasses::Id sizeExpression = m_state->relativeStackElement(_stackPosSize); + if (classes.knownZero(sizeExpression)) return GasConsumption(0); - else - return memoryGas(classes.find(Instruction::ADD, { - m_state->relativeStackElement(_stackPosOffset), - m_state->relativeStackElement(_stackPosSize) - })); + u256 const* offset = classes.knownConstant(offsetExpression); + u256 const* size = classes.knownConstant(sizeExpression); + if (!offset || !size) + return GasConsumption::infinite(); + return memoryGas(bigint(*offset) + *size); } GasMeter::GasConsumption GasMeter::memoryGasForWordArray(int _stackPosOffset, int _stackPosElementCount) @@ -304,18 +326,12 @@ GasMeter::GasConsumption GasMeter::memoryGasForWordArray(int _stackPosOffset, in ExpressionClasses& classes = m_state->expressionClasses(); // The TVM reads and charges the 32-byte length slot even for empty arrays, // so unlike memoryGas(int, int) there is no zero-size shortcut here. - ExpressionClasses::Id byteSize = classes.find(Instruction::MUL, { - m_state->relativeStackElement(_stackPosElementCount), - classes.find(u256(32)) - }); - ExpressionClasses::Id byteSizeWithLengthSlot = classes.find(Instruction::ADD, { - byteSize, - classes.find(u256(32)) - }); - return memoryGas(classes.find(Instruction::ADD, { - m_state->relativeStackElement(_stackPosOffset), - byteSizeWithLengthSlot - })); + u256 const* offset = classes.knownConstant(m_state->relativeStackElement(_stackPosOffset)); + u256 const* elementCount = classes.knownConstant(m_state->relativeStackElement(_stackPosElementCount)); + if (!offset || !elementCount) + return GasConsumption::infinite(); + bigint const byteSizeWithLengthSlot = bigint(*elementCount) * 32 + 32; + return memoryGas(bigint(*offset) + byteSizeWithLengthSlot); } namespace diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index 06a4b8b609de..3d9448104b28 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -190,6 +190,9 @@ namespace GasCosts static unsigned const extCodeHashGasInTVM = 400; static unsigned const callGasInTVM = 40; static unsigned const selfdestructGasInTVM = 5000; + static unsigned const expByteGasInTVM = 10; + static unsigned const create2WordGasInTVM = 6; + static unsigned const memorySizeLimitInTVM = 3 * 1024 * 1024; static unsigned const freezeV1GasInTVM = 20000; static unsigned const freezeExpireTimeGasInTVM = 50; @@ -267,11 +270,13 @@ class GasMeter static u256 dataGas(uint64_t _length, bool _inCreation, langutil::EVMVersion _evmVersion); private: - /// @returns _multiplier * (_value + 31) / 32, if _value is a known constant and infinite otherwise. + /// @returns _multiplier * ceil(_value / 32), if _value is a known constant and infinite otherwise. GasConsumption wordGas(u256 const& _multiplier, ExpressionClasses::Id _value); - /// @returns the gas needed to access the given memory position. + /// @returns the gas needed to access the given memory end position. /// @todo this assumes that memory was never accessed before and thus over-estimates gas usage. - GasConsumption memoryGas(ExpressionClasses::Id _position); + GasConsumption memoryGas(bigint const& _position); + /// @returns the memory gas for a known-size access starting at an offset on the stack. + GasConsumption memoryGas(ExpressionClasses::Id _offset, u256 const& _size); /// @returns the memory gas for accessing the memory at a specific offset for a number of bytes /// given as values on the stack at the given relative positions. GasConsumption memoryGas(int _stackPosOffset, int _stackPosSize); diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 7f742ec18d0b..10854c3ab8ef 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -253,7 +253,12 @@ std::string Predicate::formatSummaryCall( if (magicKind == MagicType::Kind::Block && memberName == "difficulty") memberName = "prevrandao"; - if (magicKind == MagicType::Kind::Block || magicKind == MagicType::Kind::Message || magicKind == MagicType::Kind::Transaction) + if ( + magicKind == MagicType::Kind::Block || + magicKind == MagicType::Kind::Chain || + magicKind == MagicType::Kind::Message || + magicKind == MagicType::Kind::Transaction + ) txVars.insert(magicType->toString(true) + "." + memberName); } return true; diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index ad4120839a92..d4fbc73c734b 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -741,6 +741,8 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) // not modeled explicitly, conservatively invalidate the symbolic blockchain // state so balances and other observable state cannot remain falsely stable. state().newState(); + if (!funType.returnParameterTypes().empty()) + setSymbolicUnknownValue(*m_context.expression(_funCall), m_context); m_unsupportedErrors.warning( 4588_error, _funCall.location(), @@ -1470,7 +1472,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) if (auto const* identifier = dynamic_cast(&memberExpr)) { auto const& name = identifier->name(); - solAssert(name == "block" || name == "msg" || name == "tx", ""); + solAssert(name == "block" || name == "chain" || name == "msg" || name == "tx", ""); auto memberName = _memberAccess.memberName(); // TODO remove this for 0.9.0 diff --git a/libsolidity/formal/SymbolicState.cpp b/libsolidity/formal/SymbolicState.cpp index 492e0055b008..1a7a123848cb 100644 --- a/libsolidity/formal/SymbolicState.cpp +++ b/libsolidity/formal/SymbolicState.cpp @@ -234,7 +234,14 @@ smtutil::Expression SymbolicState::txTypeConstraints() const smt::symbolicUnknownConstraints(m_tx.member("block.gaslimit"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("block.number"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("block.timestamp"), TypeProvider::uint256()) && + smt::symbolicUnknownConstraints(m_tx.member("chain.totalEnergyCurrentLimit"), TypeProvider::uint(64)) && + smt::symbolicUnknownConstraints(m_tx.member("chain.totalEnergyWeight"), TypeProvider::uint(64)) && + smt::symbolicUnknownConstraints(m_tx.member("chain.totalNetLimit"), TypeProvider::uint(64)) && + smt::symbolicUnknownConstraints(m_tx.member("chain.totalNetWeight"), TypeProvider::uint(64)) && + smt::symbolicUnknownConstraints(m_tx.member("chain.unfreezeDelayDays"), TypeProvider::uint(64)) && smt::symbolicUnknownConstraints(m_tx.member("msg.sender"), TypeProvider::address()) && + smt::symbolicUnknownConstraints(m_tx.member("msg.tokenid"), TypeProvider::trcToken()) && + smt::symbolicUnknownConstraints(m_tx.member("msg.tokenvalue"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("msg.value"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("tx.origin"), TypeProvider::address()) && smt::symbolicUnknownConstraints(m_tx.member("tx.gasprice"), TypeProvider::uint256()); @@ -242,7 +249,10 @@ smtutil::Expression SymbolicState::txTypeConstraints() const smtutil::Expression SymbolicState::txNonPayableConstraint() const { - return m_tx.member("msg.value") == 0; + return + m_tx.member("msg.value") == 0 && + m_tx.member("msg.tokenid") == 0 && + m_tx.member("msg.tokenvalue") == 0; } smtutil::Expression SymbolicState::txFunctionConstraints(FunctionDefinition const& _function) const diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 11c92a83af40..4e04aba75eeb 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -682,9 +682,16 @@ std::map transactionMemberTypes() {"block.timestamp", TypeProvider::uint256()}, {"blobhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, {"blockhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, + {"chain.totalEnergyCurrentLimit", TypeProvider::uint(64)}, + {"chain.totalEnergyWeight", TypeProvider::uint(64)}, + {"chain.totalNetLimit", TypeProvider::uint(64)}, + {"chain.totalNetWeight", TypeProvider::uint(64)}, + {"chain.unfreezeDelayDays", TypeProvider::uint(64)}, {"msg.data", TypeProvider::bytesCalldata()}, {"msg.sender", TypeProvider::address()}, {"msg.sig", TypeProvider::fixedBytes(4)}, + {"msg.tokenid", TypeProvider::trcToken()}, + {"msg.tokenvalue", TypeProvider::uint256()}, {"msg.value", TypeProvider::uint256()}, {"tx.gasprice", TypeProvider::uint256()}, {"tx.origin", TypeProvider::address()} diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 117dc0b1a07b..06a98af1d70f 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -400,7 +400,7 @@ Json formatImmutableReferences(std::map checkKeys(Json const& _input, std::set const& _keys, std::string const& _name) { - if (!_input.empty() && !_input.is_object()) + if (!_input.is_object()) return formatFatalError(Error::Type::JSONError, "\"" + _name + "\" must be an object"); for (auto const& [member, _]: _input.items()) @@ -526,7 +526,7 @@ std::optional checkMetadataKeys(Json const& _input) std::optional checkOutputSelection(Json const& _outputSelection) { - if (!_outputSelection.empty() && !_outputSelection.is_object()) + if (!_outputSelection.is_object()) return formatFatalError(Error::Type::JSONError, "\"settings.outputSelection\" must be an object"); for (auto const& [sourceName, sourceVal]: _outputSelection.items()) diff --git a/libyul/backends/evm/EVMMetrics.cpp b/libyul/backends/evm/EVMMetrics.cpp index 57593fdc26da..1d4e2be5ec02 100644 --- a/libyul/backends/evm/EVMMetrics.cpp +++ b/libyul/backends/evm/EVMMetrics.cpp @@ -115,7 +115,7 @@ bigint GasMeterVisitor::singleByteDataGas() const void GasMeterVisitor::instructionCostsInternal(evmasm::Instruction _instruction) { if (_instruction == evmasm::Instruction::EXP) - m_runGas += evmasm::GasCosts::expGas + evmasm::GasCosts::expByteGas(m_dialect.evmVersion()); + m_runGas += evmasm::GasCosts::expGas + evmasm::GasCosts::expByteGasInTVM; else if (_instruction == evmasm::Instruction::KECCAK256) // Assumes that Keccak-256 is computed on a single word (rounded up). m_runGas += evmasm::GasCosts::keccak256Gas + evmasm::GasCosts::keccak256WordGas; diff --git a/test/libevmasm/GasMeter.cpp b/test/libevmasm/GasMeter.cpp index aeac86a2931e..53dadf325ac7 100644 --- a/test/libevmasm/GasMeter.cpp +++ b/test/libevmasm/GasMeter.cpp @@ -62,6 +62,12 @@ AssemblyItems zeroArguments(size_t _count) return AssemblyItems(_count, AssemblyItem{u256(0)}); } +u256 memoryExpansionCost(u256 const& _byteSize) +{ + u256 const wordCount = (_byteSize + 31) / 32; + return GasCosts::memoryGas * wordCount + wordCount * wordCount / GasCosts::quadCoeffDiv; +} + /// Feeds the four NATIVEVOTE arguments as constants (or CALLVALUE for an unknown /// element count) and returns the estimate for the NATIVEVOTE item itself. GasMeter::GasConsumption estimateVote( @@ -138,6 +144,145 @@ BOOST_AUTO_TEST_CASE(tvm_sstore_uses_java_tron_set_and_reset_prices) BOOST_CHECK_EQUAL(reset.value, u256(GasCosts::sstoreResetGasInTVM)); } +BOOST_AUTO_TEST_CASE(tvm_exp_uses_fixed_byte_price_for_all_evm_versions) +{ + for (EVMVersion const& evmVersion: EVMVersion::allVersions()) + { + GasMeter::GasConsumption zeroExponent = estimateInstruction( + Instruction::EXP, + {u256(0), u256(2)}, + true, + evmVersion + ); + BOOST_REQUIRE(!zeroExponent.isInfinite); + BOOST_CHECK_EQUAL(zeroExponent.value, u256(GasCosts::expGas)); + + GasMeter::GasConsumption oneByteExponent = estimateInstruction( + Instruction::EXP, + {u256(1), u256(2)}, + true, + evmVersion + ); + BOOST_REQUIRE(!oneByteExponent.isInfinite); + BOOST_CHECK_EQUAL( + oneByteExponent.value, + u256(GasCosts::expGas + GasCosts::expByteGasInTVM) + ); + + GasMeter::GasConsumption fullWidthExponent = estimateInstruction( + Instruction::EXP, + {u256(-1), u256(2)}, + true, + evmVersion + ); + BOOST_REQUIRE(!fullWidthExponent.isInfinite); + BOOST_CHECK_EQUAL( + fullWidthExponent.value, + u256(GasCosts::expGas + 32 * GasCosts::expByteGasInTVM) + ); + } + + GasMeter::GasConsumption unknownExponent = estimateInstruction( + Instruction::EXP, + {AssemblyItem(Instruction::CALLVALUE), AssemblyItem(u256(2))} + ); + BOOST_REQUIRE(!unknownExponent.isInfinite); + BOOST_CHECK_EQUAL( + unknownExponent.value, + u256(GasCosts::expGas + 32 * GasCosts::expByteGasInTVM) + ); +} + +BOOST_AUTO_TEST_CASE(tvm_create2_charges_hash_cost_per_init_code_word) +{ + for (unsigned size: {0u, 1u, 32u, 33u}) + { + GasMeter::GasConsumption create = estimateInstruction( + Instruction::CREATE, + {u256(size), u256(0), u256(0)}, + false + ); + GasMeter::GasConsumption create2 = estimateInstruction( + Instruction::CREATE2, + {u256(0), u256(size), u256(0), u256(0)}, + false + ); + BOOST_REQUIRE(!create.isInfinite); + BOOST_REQUIRE(!create2.isInfinite); + u256 const wordCount = (u256(size) + 31) / 32; + u256 const expectedCreateCost = GasCosts::createGas + memoryExpansionCost(size); + BOOST_CHECK_EQUAL(create.value, expectedCreateCost); + BOOST_CHECK_EQUAL( + create2.value, + expectedCreateCost + GasCosts::create2WordGasInTVM * wordCount + ); + } +} + +BOOST_AUTO_TEST_CASE(tvm_memory_limit_and_address_overflow_are_unbounded) +{ + u256 const memoryLimit = GasCosts::memorySizeLimitInTVM; + GasMeter::GasConsumption atLimit = estimateInstruction( + Instruction::MSTORE8, + {u256(1), memoryLimit - 1} + ); + BOOST_REQUIRE(!atLimit.isInfinite); + BOOST_CHECK_EQUAL( + atLimit.value, + u256(GasMeter::runGas(Instruction::MSTORE8, EVMVersion{})) + memoryExpansionCost(memoryLimit) + ); + + GasMeter::GasConsumption aboveLimit = estimateInstruction( + Instruction::MSTORE8, + {u256(1), memoryLimit} + ); + BOOST_CHECK(aboveLimit.isInfinite); + + GasMeter::GasConsumption wrappedEnd = estimateInstruction( + Instruction::MSTORE8, + {u256(1), u256(-1)} + ); + BOOST_CHECK(wrappedEnd.isInfinite); + + // As in java-tron's memNeeded(), a zero-sized access does not expand memory, + // regardless of the offset value. + GasMeter::GasConsumption zeroSizeAtMaxOffset = estimateInstruction( + Instruction::RETURN, + {u256(0), u256(-1)} + ); + BOOST_REQUIRE(!zeroSizeAtMaxOffset.isInfinite); + BOOST_CHECK_EQUAL(zeroSizeAtMaxOffset.value, u256(0)); +} + +BOOST_AUTO_TEST_CASE(mcopy_charges_memory_expansion_to_the_larger_end) +{ + GasMeter::GasConsumption overlappingRanges = estimateInstruction( + Instruction::MCOPY, + {u256(64), u256(0), u256(32)}, + true, + EVMVersion::cancun() + ); + BOOST_REQUIRE(!overlappingRanges.isInfinite); + BOOST_CHECK_EQUAL( + overlappingRanges.value, + u256(GasMeter::runGas(Instruction::MCOPY, EVMVersion::cancun())) + + 2 * GasCosts::copyGas + + memoryExpansionCost(96) + ); + + GasMeter::GasConsumption zeroSizeAtMaxOffsets = estimateInstruction( + Instruction::MCOPY, + {u256(0), u256(-1), u256(-1)}, + true, + EVMVersion::cancun() + ); + BOOST_REQUIRE(!zeroSizeAtMaxOffsets.isInfinite); + BOOST_CHECK_EQUAL( + zeroSizeAtMaxOffsets.value, + u256(GasMeter::runGas(Instruction::MCOPY, EVMVersion::cancun())) + ); +} + BOOST_AUTO_TEST_CASE(tvm_call_family_uses_fixed_base_and_conditional_transfer_prices) { for (Instruction instruction: {Instruction::DELEGATECALL, Instruction::STATICCALL}) @@ -233,6 +378,28 @@ BOOST_AUTO_TEST_CASE(nativevote_with_unknown_element_count_is_unbounded) BOOST_CHECK(gas.isInfinite); } +BOOST_AUTO_TEST_CASE(nativevote_checks_memory_limit_without_u256_wraparound) +{ + u256 const maxElementCount = GasCosts::memorySizeLimitInTVM / 32 - 1; + GasMeter::GasConsumption atLimit = estimateVote(u256(0), maxElementCount, u256(0), u256(0)); + BOOST_REQUIRE(!atLimit.isInfinite); + BOOST_CHECK_EQUAL( + atLimit.value, + u256(GasCosts::voteGasInTVM) + memoryExpansionCost(GasCosts::memorySizeLimitInTVM) + ); + + GasMeter::GasConsumption aboveLimit = estimateVote(u256(0), maxElementCount + 1, u256(0), u256(0)); + BOOST_CHECK(aboveLimit.isInfinite); + + GasMeter::GasConsumption wrappedProduct = estimateVote( + u256(0), + u256(1) << 251, + u256(0), + u256(0) + ); + BOOST_CHECK(wrappedProduct.isInfinite); +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index b53205e959e5..a70c88aa4058 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include @@ -48,6 +50,21 @@ namespace solidity::frontend::test namespace { + class ComputeMethodProbe: private ComputeMethod + { + public: + static bigint gasNeededFor(AssemblyItems const& _routine, EVMVersion _evmVersion) + { + u256 value = 0; + Params params{/* isCreation = */ false, /* runs = */ 1, /* multiplicity = */ 0, _evmVersion}; + ComputeMethodProbe probe(params, value); + return probe.ComputeMethod::gasNeeded(_routine); + } + + private: + ComputeMethodProbe(Params const& _params, u256 const& _value): ComputeMethod(_params, _value) {} + }; + AssemblyItems addDummyLocations(AssemblyItems const& _input) { // add dummy locations to each item so that we can check that they are not deleted @@ -157,6 +174,15 @@ namespace BOOST_AUTO_TEST_SUITE(Optimiser) +BOOST_AUTO_TEST_CASE(constant_optimizer_exp_uses_tvm_fixed_byte_cost) +{ + for (EVMVersion const& evmVersion: EVMVersion::allVersions()) + BOOST_CHECK_EQUAL( + ComputeMethodProbe::gasNeededFor({Instruction::EXP}, evmVersion), + GasCosts::expGas + GasCosts::expByteGasInTVM + ); +} + BOOST_AUTO_TEST_CASE(cse_push_immutable_same) { AssemblyItem pushImmutable{PushImmutable, 0x1234}; diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 34b268b75616..b2eeb8738390 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -323,6 +323,42 @@ BOOST_AUTO_TEST_CASE(assume_object_input) BOOST_CHECK(!containsAtMostWarnings(result)); } +BOOST_AUTO_TEST_CASE(settings_must_be_an_object) +{ + frontend::StandardCompiler compiler; + for (Json const& invalidSettings: {Json(nullptr), Json::array()}) + { + Json input = SolidityCode().json(); + input["settings"] = invalidSettings; + Json result = compiler.compile(input); + BOOST_CHECK(containsError(result, "JSONError", "\"settings\" must be an object")); + } +} + +BOOST_AUTO_TEST_CASE(metadata_settings_must_be_an_object) +{ + frontend::StandardCompiler compiler; + for (Json const& invalidMetadataSettings: {Json(nullptr), Json::array()}) + { + Json input = SolidityCode().json(); + input["settings"]["metadata"] = invalidMetadataSettings; + Json result = compiler.compile(input); + BOOST_CHECK(containsError(result, "JSONError", "\"settings.metadata\" must be an object")); + } +} + +BOOST_AUTO_TEST_CASE(output_selection_must_be_an_object) +{ + frontend::StandardCompiler compiler; + for (Json const& invalidOutputSelection: {Json(nullptr), Json::array()}) + { + Json input = SolidityCode().json(); + input["settings"]["outputSelection"] = invalidOutputSelection; + Json result = compiler.compile(input); + BOOST_CHECK(containsError(result, "JSONError", "\"settings.outputSelection\" must be an object")); + } +} + BOOST_AUTO_TEST_CASE(invalid_language) { char const* input = R"( diff --git a/test/libsolidity/smtCheckerTests/tron/magic_members.sol b/test/libsolidity/smtCheckerTests/tron/magic_members.sol new file mode 100644 index 000000000000..2490de027d66 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/magic_members.sol @@ -0,0 +1,39 @@ +contract C { + function chainParameters() external view { + assert(chain.totalNetLimit <= type(uint64).max); + assert(chain.totalNetWeight <= type(uint64).max); + assert(chain.totalEnergyCurrentLimit <= type(uint64).max); + assert(chain.totalEnergyWeight <= type(uint64).max); + assert(chain.unfreezeDelayDays <= type(uint64).max); + } + + function tokenCallParameterRanges() external payable { + assert(msg.tokenvalue <= type(uint256).max); + assert(msg.tokenid <= type(trcToken).max); + } + + function nonPayableTokenCallParameters() external view { + (uint256 trxValue, uint256 tokenValue, trcToken tokenId) = readTokenCallParameters(); + assert(trxValue == 0); + assert(tokenValue == 0); + assert(tokenId == 0); + } + + function readTokenCallParameters() internal view returns (uint256, uint256, trcToken) { + return (msg.value, msg.tokenvalue, msg.tokenid); + } +} +// ==== +// SMTEngine: chc +// SMTShowProvedSafe: yes +// ---- +// Info 9576: (59-106): CHC: Assertion violation check is safe! +// Info 9576: (110-158): CHC: Assertion violation check is safe! +// Info 9576: (162-219): CHC: Assertion violation check is safe! +// Info 9576: (223-274): CHC: Assertion violation check is safe! +// Info 9576: (278-329): CHC: Assertion violation check is safe! +// Info 9576: (393-436): CHC: Assertion violation check is safe! +// Info 9576: (440-481): CHC: Assertion violation check is safe! +// Info 9576: (635-656): CHC: Assertion violation check is safe! +// Info 9576: (660-683): CHC: Assertion violation check is safe! +// Info 9576: (687-707): CHC: Assertion violation check is safe! diff --git a/test/libsolidity/smtCheckerTests/tron/magic_members_bmc.sol b/test/libsolidity/smtCheckerTests/tron/magic_members_bmc.sol new file mode 100644 index 000000000000..c53d218872a0 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/magic_members_bmc.sol @@ -0,0 +1,39 @@ +contract C { + function chainParameters() external view { + assert(chain.totalNetLimit <= type(uint64).max); + assert(chain.totalNetWeight <= type(uint64).max); + assert(chain.totalEnergyCurrentLimit <= type(uint64).max); + assert(chain.totalEnergyWeight <= type(uint64).max); + assert(chain.unfreezeDelayDays <= type(uint64).max); + } + + function tokenCallParameterRanges() external payable { + assert(msg.tokenvalue <= type(uint256).max); + assert(msg.tokenid <= type(trcToken).max); + } + + function nonPayableTokenCallParameters() external view { + (uint256 trxValue, uint256 tokenValue, trcToken tokenId) = readTokenCallParameters(); + assert(trxValue == 0); + assert(tokenValue == 0); + assert(tokenId == 0); + } + + function readTokenCallParameters() internal view returns (uint256, uint256, trcToken) { + return (msg.value, msg.tokenvalue, msg.tokenid); + } +} +// ==== +// SMTEngine: bmc +// SMTShowProvedSafe: yes +// ---- +// Info 2961: (59-106): BMC: Assertion violation check is safe! +// Info 2961: (110-158): BMC: Assertion violation check is safe! +// Info 2961: (162-219): BMC: Assertion violation check is safe! +// Info 2961: (223-274): BMC: Assertion violation check is safe! +// Info 2961: (278-329): BMC: Assertion violation check is safe! +// Info 2961: (393-436): BMC: Assertion violation check is safe! +// Info 2961: (440-481): BMC: Assertion violation check is safe! +// Info 2961: (635-656): BMC: Assertion violation check is safe! +// Info 2961: (660-683): BMC: Assertion violation check is safe! +// Info 2961: (687-707): BMC: Assertion violation check is safe! diff --git a/test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges.sol b/test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges.sol new file mode 100644 index 000000000000..85a11e082ab8 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges.sol @@ -0,0 +1,23 @@ +contract C { + function withdrawReward() external { + assert(withdrawreward() <= type(uint256).max); + } + + function cancelAllUnfreezeV2() external { + assert(cancelallunfreezev2() <= type(uint256).max); + } + + function withdrawExpireUnfreeze() external { + assert(withdrawexpireunfreeze() <= type(uint256).max); + } +} +// ==== +// SMTEngine: chc +// SMTShowProvedSafe: yes +// ---- +// Warning 4588: (60-76): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Warning 4588: (156-177): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Warning 4588: (260-284): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Info 9576: (53-98): CHC: Assertion violation check is safe! +// Info 9576: (149-199): CHC: Assertion violation check is safe! +// Info 9576: (253-306): CHC: Assertion violation check is safe! diff --git a/test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges_bmc.sol b/test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges_bmc.sol new file mode 100644 index 000000000000..e1f83a097835 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/state_mutation_return_ranges_bmc.sol @@ -0,0 +1,23 @@ +contract C { + function withdrawReward() external { + assert(withdrawreward() <= type(uint256).max); + } + + function cancelAllUnfreezeV2() external { + assert(cancelallunfreezev2() <= type(uint256).max); + } + + function withdrawExpireUnfreeze() external { + assert(withdrawexpireunfreeze() <= type(uint256).max); + } +} +// ==== +// SMTEngine: bmc +// SMTShowProvedSafe: yes +// ---- +// Warning 4588: (60-76): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Warning 4588: (156-177): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Warning 4588: (260-284): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Info 2961: (53-98): BMC: Assertion violation check is safe! +// Info 2961: (149-199): BMC: Assertion violation check is safe! +// Info 2961: (253-306): BMC: Assertion violation check is safe! diff --git a/test/libyul/Metrics.cpp b/test/libyul/Metrics.cpp index 9e74cd150e49..ce97b0d66bd3 100644 --- a/test/libyul/Metrics.cpp +++ b/test/libyul/Metrics.cpp @@ -25,10 +25,14 @@ #include #include +#include +#include #include #include #include +#include + #include using namespace solidity::langutil; @@ -384,4 +388,21 @@ BOOST_FIXTURE_TEST_CASE(switch_statement_large_custom_weights, CustomWeightFixtu BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE(YulEVMMetrics) + +BOOST_AUTO_TEST_CASE(exp_uses_tvm_fixed_byte_cost) +{ + for (EVMVersion const& evmVersion: EVMVersion::allVersions()) + { + auto const [runCost, dataCost] = GasMeterVisitor::instructionCosts( + evmasm::Instruction::EXP, + EVMDialect::strictAssemblyForEVM(evmVersion, std::nullopt) + ); + BOOST_CHECK_EQUAL(runCost, evmasm::GasCosts::expGas + evmasm::GasCosts::expByteGasInTVM); + BOOST_CHECK_EQUAL(dataCost, evmasm::GasCosts::createDataGas); + } +} + +BOOST_AUTO_TEST_SUITE_END() + } From 364cfd36ed3992e89d5655b2caae743ccdb45810 Mon Sep 17 00:00:00 2001 From: Asuka Date: Fri, 31 Jul 2026 07:17:23 +0800 Subject: [PATCH 121/121] fix: align SMT library constraints and JSON validation --- libsolidity/formal/SymbolicState.cpp | 6 +- libsolidity/interface/StandardCompiler.cpp | 45 ++++++------ test/libsolidity/StandardCompiler.cpp | 72 +++++++++++++++++-- .../smtCheckerTests/special/ether_units.sol | 17 ----- .../smtCheckerTests/special/trx_units.sol | 17 +++++ .../library_nonpayable_transaction_values.sol | 14 ++++ ...rary_nonpayable_transaction_values_bmc.sol | 14 ++++ .../smtCheckerTests/types/address_balance.sol | 6 +- 8 files changed, 145 insertions(+), 46 deletions(-) delete mode 100644 test/libsolidity/smtCheckerTests/special/ether_units.sol create mode 100644 test/libsolidity/smtCheckerTests/special/trx_units.sol create mode 100644 test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values.sol create mode 100644 test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values_bmc.sol diff --git a/libsolidity/formal/SymbolicState.cpp b/libsolidity/formal/SymbolicState.cpp index 1a7a123848cb..8e55922ae573 100644 --- a/libsolidity/formal/SymbolicState.cpp +++ b/libsolidity/formal/SymbolicState.cpp @@ -257,7 +257,11 @@ smtutil::Expression SymbolicState::txNonPayableConstraint() const smtutil::Expression SymbolicState::txFunctionConstraints(FunctionDefinition const& _function) const { - smtutil::Expression conj = _function.isPayable() ? smtutil::Expression(true) : txNonPayableConstraint(); + // Library functions inherit the caller's transaction values through DELEGATECALL. + smtutil::Expression conj = + (_function.isPayable() || _function.libraryFunction()) ? + smtutil::Expression(true) : + txNonPayableConstraint(); if (_function.isPartOfExternalInterface()) { auto sig = TypeProvider::function(_function)->externalIdentifier(); diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 06a98af1d70f..c1e6ae0b8dab 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -649,6 +649,8 @@ std::variant StandardCompiler::parseI if (auto result = checkRootKeys(_input)) return *result; + if (_input.contains("language") && !_input["language"].is_string()) + return formatFatalError(Error::Type::JSONError, "\"language\" must be a string."); ret.language = _input.value("language", ""); Json const& sources = _input.value("sources", Json()); @@ -772,31 +774,28 @@ std::variant StandardCompiler::parseI if (!auxInputs.empty()) { Json const& smtlib2Responses = auxInputs.value("smtlib2responses", Json::object()); - if (!smtlib2Responses.empty()) - { - if (!smtlib2Responses.is_object()) - return formatFatalError(Error::Type::JSONError, "\"auxiliaryInput.smtlib2responses\" must be an object."); + if (!smtlib2Responses.is_object()) + return formatFatalError(Error::Type::JSONError, "\"auxiliaryInput.smtlib2responses\" must be an object."); - for (auto const& [hashString, response]: smtlib2Responses.items()) + for (auto const& [hashString, response]: smtlib2Responses.items()) + { + util::h256 hash; + try { - util::h256 hash; - try - { - hash = util::h256(hashString); - } - catch (util::BadHexCharacter const&) - { - return formatFatalError(Error::Type::JSONError, "Invalid hex encoding of SMTLib2 auxiliary input."); - } + hash = util::h256(hashString); + } + catch (util::BadHexCharacter const&) + { + return formatFatalError(Error::Type::JSONError, "Invalid hex encoding of SMTLib2 auxiliary input."); + } - if (!response.is_string()) - return formatFatalError( - Error::Type::JSONError, - "\"smtlib2Responses." + hashString + "\" must be a string." - ); + if (!response.is_string()) + return formatFatalError( + Error::Type::JSONError, + "\"smtlib2Responses." + hashString + "\" must be a string." + ); - ret.smtLib2Responses[hash] = response.get(); - } + ret.smtLib2Responses[hash] = response.get(); } } @@ -872,7 +871,11 @@ std::variant StandardCompiler::parseI std::vector components; for (Json const& arrayValue: settings["debug"]["debugInfo"]) + { + if (!arrayValue.is_string()) + return formatFatalError(Error::Type::JSONError, "Every value in settings.debug.debugInfo must be a string."); components.push_back(arrayValue.get()); + } std::optional debugInfoSelection = DebugInfoSelection::fromComponents( components, diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index b2eeb8738390..0a86bb40b652 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -359,6 +359,42 @@ BOOST_AUTO_TEST_CASE(output_selection_must_be_an_object) } } +BOOST_AUTO_TEST_CASE(language_must_be_a_string) +{ + frontend::StandardCompiler compiler; + for (Json const& invalidLanguage: {Json(nullptr), Json::array()}) + { + Json input = SolidityCode().json(); + input["language"] = invalidLanguage; + Json result = compiler.compile(input); + BOOST_CHECK(containsError(result, "JSONError", "\"language\" must be a string.")); + } +} + +BOOST_AUTO_TEST_CASE(smtlib2responses_must_be_an_object) +{ + frontend::StandardCompiler compiler; + for (Json const& invalidResponses: {Json(nullptr), Json::array()}) + { + Json input = SolidityCode().json(); + input["auxiliaryInput"]["smtlib2responses"] = invalidResponses; + Json result = compiler.compile(input); + BOOST_CHECK(containsError(result, "JSONError", "\"auxiliaryInput.smtlib2responses\" must be an object.")); + } +} + +BOOST_AUTO_TEST_CASE(debug_info_components_must_be_strings) +{ + frontend::StandardCompiler compiler; + for (Json const& invalidComponent: {Json(nullptr), Json(1)}) + { + Json input = SolidityCode().json(); + input["settings"]["debug"]["debugInfo"] = Json::array({invalidComponent}); + Json result = compiler.compile(input); + BOOST_CHECK(containsError(result, "JSONError", "Every value in settings.debug.debugInfo must be a string.")); + } +} + BOOST_AUTO_TEST_CASE(invalid_language) { char const* input = R"( @@ -564,9 +600,9 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK(contract["evm"]["bytecode"]["object"].is_string()); BOOST_CHECK_EQUAL( solidity::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].get()), - std::string("6080604052348015600e575f5ffd5b5060") + + std::string("6080604052348015600e575f5ffd5b50d380156019575f5ffd5b50d280156024575f5ffd5b5060") + (VersionIsRelease ? "3e" : util::toHex(bytes{uint8_t(60 + VersionStringStrict.size())})) + - "80601a5f395ff3fe60806040525f5ffdfe" + "8060305f395ff3fe60806040525f5ffdfe" ); BOOST_CHECK(contract["evm"]["assembly"].is_string()); BOOST_CHECK(contract["evm"]["assembly"].get().find( @@ -574,10 +610,16 @@ BOOST_AUTO_TEST_CASE(basic_compilation) "callvalue\n dup1\n " "iszero\n tag_1\n jumpi\n " "revert(0x00, 0x00)\n" - "tag_1:\n pop\n dataSize(sub_0)\n dup1\n " + "tag_1:\n pop\n calltokenid\n dup1\n " + "iszero\n tag_2\n jumpi\n " + "revert(0x00, 0x00)\n" + "tag_2:\n pop\n calltokenvalue\n dup1\n " + "iszero\n tag_3\n jumpi\n " + "revert(0x00, 0x00)\n" + "tag_3:\n pop\n dataSize(sub_0)\n dup1\n " "dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n " "/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n " - "revert(0x00, 0x00)\n\n auxdata: 0xa26469706673582212" + "revert(0x00, 0x00)\n\n auxdata: 0xa26474726f6e582212" ) == 0); BOOST_CHECK(contract["evm"]["gasEstimates"].is_object()); BOOST_CHECK_EQUAL(contract["evm"]["gasEstimates"].size(), 1); @@ -611,6 +653,28 @@ BOOST_AUTO_TEST_CASE(basic_compilation) "{\"begin\":0,\"end\":14,\"name\":\"tag\",\"source\":0,\"value\":\"1\"}," "{\"begin\":0,\"end\":14,\"name\":\"JUMPDEST\",\"source\":0}," "{\"begin\":0,\"end\":14,\"name\":\"POP\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"CALLTOKENID\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"ISZERO\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH [tag]\",\"source\":0,\"value\":\"2\"}," + "{\"begin\":0,\"end\":14,\"name\":\"JUMPI\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"}," + "{\"begin\":0,\"end\":14,\"name\":\"REVERT\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"tag\",\"source\":0,\"value\":\"2\"}," + "{\"begin\":0,\"end\":14,\"name\":\"JUMPDEST\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"POP\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"CALLTOKENVALUE\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"ISZERO\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH [tag]\",\"source\":0,\"value\":\"3\"}," + "{\"begin\":0,\"end\":14,\"name\":\"JUMPI\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"}," + "{\"begin\":0,\"end\":14,\"name\":\"REVERT\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"tag\",\"source\":0,\"value\":\"3\"}," + "{\"begin\":0,\"end\":14,\"name\":\"JUMPDEST\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"POP\",\"source\":0}," "{\"begin\":0,\"end\":14,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}," "{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0}," "{\"begin\":0,\"end\":14,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}," diff --git a/test/libsolidity/smtCheckerTests/special/ether_units.sol b/test/libsolidity/smtCheckerTests/special/ether_units.sol deleted file mode 100644 index 9c0e8ea71ff0..000000000000 --- a/test/libsolidity/smtCheckerTests/special/ether_units.sol +++ /dev/null @@ -1,17 +0,0 @@ -contract D { - function f() public pure { - assert(1000000000000000000 wei == 1 ether); - assert(100000000000000000 wei == 1 ether); - assert(1000000000 wei == 1 gwei); - assert(100000000 wei == 1 gwei); - assert(1000000000 gwei == 1 ether); - assert(100000000 gwei == 1 ether); - } -} -// ==== -// SMTEngine: all -// ---- -// Warning 6328: (89-130): CHC: Assertion violation happens here. -// Warning 6328: (170-201): CHC: Assertion violation happens here. -// Warning 6328: (243-276): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/special/trx_units.sol b/test/libsolidity/smtCheckerTests/special/trx_units.sol new file mode 100644 index 000000000000..3f0d75021d14 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/special/trx_units.sol @@ -0,0 +1,17 @@ +contract D { + function f() public pure { + assert(1000000 sun == 1 trx); + assert(100000 sun == 1 trx); + assert(1 sun == 1); + assert(2 sun == 1); + assert(2 trx == 2000000 sun); + assert(2 trx == 200000 sun); + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (75-102): CHC: Assertion violation happens here. +// Warning 6328: (128-146): CHC: Assertion violation happens here. +// Warning 6328: (182-209): CHC: Assertion violation happens here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values.sol b/test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values.sol new file mode 100644 index 000000000000..f8e2e9cbdfd8 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values.sol @@ -0,0 +1,14 @@ +library L { + function check() public view { + assert(msg.value == 0); + assert(msg.tokenvalue == 0); + assert(msg.tokenid == 0); + } +} +// ==== +// SMTEngine: chc +// SMTIgnoreCex: yes +// ---- +// Warning 6328: (46-68): CHC: Assertion violation happens here. +// Warning 6328: (72-99): CHC: Assertion violation happens here. +// Warning 6328: (103-127): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values_bmc.sol b/test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values_bmc.sol new file mode 100644 index 000000000000..2f429cc51635 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/library_nonpayable_transaction_values_bmc.sol @@ -0,0 +1,14 @@ +library L { + function check() public view { + assert(msg.value == 0); + assert(msg.tokenvalue == 0); + assert(msg.tokenid == 0); + } +} +// ==== +// SMTEngine: bmc +// SMTIgnoreCex: yes +// ---- +// Warning 4661: (46-68): BMC: Assertion violation happens here. +// Warning 4661: (72-99): BMC: Assertion violation happens here. +// Warning 4661: (103-127): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/types/address_balance.sol b/test/libsolidity/smtCheckerTests/types/address_balance.sol index a24fa32b18d2..3ca116ffb792 100644 --- a/test/libsolidity/smtCheckerTests/types/address_balance.sol +++ b/test/libsolidity/smtCheckerTests/types/address_balance.sol @@ -1,7 +1,7 @@ contract C { function f(address a, address b) public view { - uint x = b.balance + 1000 ether; + uint x = b.balance + 1000 trx; assert(a.balance > b.balance); } } @@ -10,5 +10,5 @@ contract C // SMTIgnoreCex: yes // ---- // Warning 2072: (63-69): Unused local variable. -// Warning 4984: (72-94): CHC: Overflow (resulting value larger than 2**256 - 1) happens here. -// Warning 6328: (98-127): CHC: Assertion violation happens here. +// Warning 4984: (72-92): CHC: Overflow (resulting value larger than 2**256 - 1) happens here. +// Warning 6328: (96-125): CHC: Assertion violation happens here.